<h1 align="center">
	<a href="https://apicart.net/" target="_blank">
		<img src="https://apicart.net/assets/images/logo/logo.purple.svg" alt="" width="100">
	</a>
	<br>
	<br>
	Js-Utils
	<br>
	<img src="https://travis-ci.org/apicart/packages-js.svg?branch=master" alt="">
	<img alt="GitHub tag (latest by date)" src="https://img.shields.io/github/v/tag/apicart/packages-js">
</h1>

Website: [https://apicart.net](https://apicart.net)<br>
Sign Up: [https://accounts.apicart.net/](https://accounts.apicart.net/)<br>

- A small set of useful utilities for simpler development.
- ✅ **7 Kb minified (3 Kb Gzipped)**
- ✅ Supports IE 10 +
- ✅ [TRY IT ON CODEPEN](https://codepen.io/apicart/pen/Vqorov)

**Content**
- [Ajax](https://github.com/apicart/js-utils#ajax-utilsajax)
- [Console](https://github.com/apicart/js-utils#console-utilsconsole)
- [DOM](https://github.com/apicart/js-utils#dom-utilsdom)
- [JSON](https://github.com/apicart/js-utils#json-utilsjson)
- [LocalStorage](https://github.com/apicart/js-utils#utils-localstorage)
- [Loops](https://github.com/apicart/js-utils#loops-utilsloops)
- [Objects](https://github.com/apicart/js-utils#objects-utilsobjects)
- [Strings](https://github.com/apicart/js-utils#strings-utilsstrings)
- [Url](https://github.com/apicart/js-utils#url-utilsurl)
- [Validators](https://github.com/apicart/js-utils#validators-utilsvalidators)
- [Data Binder](https://github.com/apicart/js-utils#data-binder-utilsdatabinder)
- [Event Dispatcher](https://github.com/apicart/js-utils#event-dispatcher-utilseventdispatcher)
- [Flash Messages](https://github.com/apicart/js-utils#flash-messages-utilsflashmessages)

## Installation

### Cdn
```html
<!-- Master version from Github -->
<script src="https://cdn.jsdelivr.net/gh/apicart/js-utils/dist/utils.min.js"></script>

<!-- v1.0.0-alpha1 from jsdelivr.net -->
<script src="https://cdn.jsdelivr.net/npm/@apicart/js-utils@1.0.0-alpha1/dist/utils.min.js" integrity="sha256-eo4u9fSxiYhrAT7PpLhbWEFHsiuBnTV0krDfY7VeQE4=" crossorigin="anonymous"></script>
```

### Npm & Yarn
```
npm i @apicart/js-utils

yarn add @apicart/js-utils
```

## Ajax (Utils.ajax)
This component simplifies work with the XMLHttpRequest.

**Parameters**

| Parameter     | async   | cache   | data   | headers | method | queryParameters | timeout | url    | withCredentials | start         | complete      |
|---------------|---------|---------|--------|---------|--------|-----------------|---------|--------|-----------------|---------------|---------------|
| Type          | boolean | boolean | object | object  | string | object          | number  | string | boolean         | function      | function      |
| Default value | true    | true    | {}     | {}      | get    | {}              | 5000    | ''     | false           | function() {} | function() {} |

```typescript
get(url: string, parameters: any = {}): Promise<any>
post(url: string, parameters: any = {}): Promise<any>
request(parameters: any = {}): Promise<any>
```
```js
Utils.Ajax.get('https://example.com', {
    complete: function (response){
        alert('Done');
    }
});

Utils.Ajax.post('https://example.com', {
    complete: function (response){
        alert('Done');
    }
});

Utils.Ajax.request({
    url: 'https://example.com',
    method: 'post',
    complete: function (response){
        alert('Done');
    }
});
```

## Console (Utils.Console)
Wraps the default browser console and ensures the cross-browser compatibility.
```typescript
error(...args: any[]): Console
```

```js
Utils.Console.error('Some', 'Value');
```

```typescript
log(...args: any[]): Console
```

```js
Utils.Console.log('Some', 'Value');
```

```typescript
warn(...args: any[]): this
```

```js
Utils.Console.warn('Some', 'Value');
```

## DOM (Utils.Dom)
Simplifies work with Document Object Model.

```typescript
addClass(element: Element, classes: string|string[]): Dom
```

Adds one or multiple classes to selected elements.
```js
Utils.Dom.addClass(document.querySelector('.element'), 'first second third');
```

```typescript
findParent(element: Element, selector: string): Element|null
```

Returns element parent based on selector. If the parent was not found, returns null.
```js
Utils.Dom.findParent(Element $element, '.parent');
```

```typescript
matches(element: Element, selector: string): boolean
```

Returns true if element matches selector. If not, returns false.
```js
Utils.Dom.matches(document.querySelector('.element', '.selected');
```

```typescript
on(eventTypes: string|string[], selectors: string|string[], callback: Function): this
```

Adds event listener to selected elements. Works even on dynamically added elements.
```js
Utils.Dom.on('click', '.element', function() {...});
```


```typescript
removeClass(element: Element, classes: string): Dom
```

Removes one or multiple classes from selected elements.
```js
Utils.Dom.removeClass(document.querySelector('.element'), 'first second third');
```

```typescript
trigger(element: any[], event: string): this
```

Triggers an event on selected element.
```js
Utils.Dom.trigger(document.querySelector('.button'), 'click');
```

## Event Dispatcher (Utils.eventDispatcher)

Event dispatcher allows you communicate between components based on events.
If for example a product was added into the cart, you can trigger `productAddedIntoCart` event.
Listeners waiting for this event will be triggered with given values.

```typescript
addListener(listenerKey: string, event: string|string[], callback: Function, singleAction: boolean = false): EventDispatcher
```

This method registers listener. If the `singleAction` parameter is set to true, the listener will be triggered only once (it is useful for dynamically generated listeners).
```js
Utils.EventDispatcher.addListener('number-dumper', 'send-number', function (number) {
    console.log(number);
}, true); // Single action is set to true, so the listener will be triggered only once
Utils.EventDispatcher.addListener('product-popup', 'product-added-into-cart', function (parameters) {...});
```

```typescript
removeListener(listenerKey: string, event: string|string[]): this
```

Removes listener from given event.
```js
Utils.EventDispatcher.removeListener('listener', 'event1 event2');
Utils.EventDispatcher.removeListener('listener', ['event1', 'event2']);
Utils.EventDispatcher.removeListener('number-dumper', 'send-number');
```

```typescript
dispatchEvent(event: string|string[], parameters: any|null = []): EventDispatcher
```

Triggers selected event. Given parameters are provided to the listeners.
```js
Utils.EventDispatcher.dispatchEvent('event1 event2');
Utils.EventDispatcher.dispatchEvent(['event1', 'event2']);
Utils.EventDispatcher.dispatchEvent('rozesli-cislo', 1);
```

## Json (Utils.Json)
```typescript
isJson(content: any|null): boolean
```

Checks if the provided data are json. If not returns false.
```js
Utils.Json.isJson('{a: "b"}'); // true
Utils.Json.isJson('Text'); // false
```

```typescript
parse(content: any|null): any
```

Converts json to object. If the provided data are not json, returns an empty object.
```js
Utils.Json.parse('{a: "b"}'); // {a: "b"}
```

```typescript
stringify(object: any): string
```

Converts javascript object into json.
```js
Utils.Json.stringify({a: "b"}); // "{a: "b"}"
```

## Local Storage (Utils.LocalStorage)

```typescript
clear(): this
```
Clears local storage
```js
Utils.LocalStorage.clear();
```

```typescript
getItem(key: string): any | null
```
Returns item parsed as json

```js
Utils.LocalStorage.getItem('someItem');
```

```typescript
setItem(key: string, value: any, expiration: number | null = null): this
```
Saves item into local storage. Automatically converts any possible type into json and stringifies it.

```
Utils.LocalStorage.setItem('someItem', {a: 1});
```

```typescript
removeItem(key: string): this
```
Removes item from local storage.

```js
Utils.LocalStorage.removeItem('someItem');
```

```typescript
hasItem(key: string): boolean
```
Returns true if given key exists in the local storage

```js
Utils.LocalStorage.hasItem('someItem');
```

```typescript
getActualTimestamp(): number
```
Returns actual time in timestamp
```js
Utils.LocalStorage.getActualTimestamp();
```


## Loops (Utils.Loops)

```typescript
forEach(iterable: any | null, callback: Function): Loops
```

Function that is able to iterate over objects and arrays. Inside this function the `this` object is an object containing *counter, iterableLength* parameters and *isFirst, isLast, isEven, isOdd* functions.

```js
Utils.Loops.forEach([1, 2, 3], function(value, key) {...});
Utils.Loops.forEach([1, 2, 3], function(value, key) {console.log(this.counter, this.isFirst());...});
Utils.Loops.forEach(document.querySelectorAll('.element'), function(element, key) {...});
```

## Objects (Utils.Objects)

```typescript
assign(object: Object, keyPath: string|string[], value: any): void
```

Polyfill of the Object.assign for older browsers. Is able to assign nested properties.
```js
var a = {x: 1};
Utils.Objects.assign(a, 'y.z', 2); // {x: 1, y: {z: 2}}
```

```
copy(object: Object): Object
```

Returns a new copy of the provided object. Object copy is without a reference to copied object.
```js
Utils.Objects.copy({a: "b"}); // {a: "b"}
```

```
delete(object: Object, keyPath: string|string[]): void
```

Removes keys from object. Is able to remove nested keys.
```js
Utils.Objects.delete({a: {b: {c: "1", d: "2"}}}, 'a.b.c'); // {a: {b: {d: "2"}}}
```

```
find(object: Object, keyPath: string|string[]): any | null
```

This method is able to find a value according to provided key. The key can be arbitrarily nested. If the key doesnt exists, returns null.
```js
Utils.Objects.find({a: {b: {c: "1"}}}, 'a.b.c'); // 1
```

```
keyExists(object: Object, keyPath: string|string[]): boolean
```

Returns true if given path exists

```js
Utils.Objects.keyExists('some.nested.key');
```

```typescript
isObject(data: any): boolean
```

Checks if the provided data are object.
```js
Utils.Objects.isObject({a: "b"}); // true
Utils.Objects.isObject(null); // false
Utils.Objects.isObject([]); // false
```

```typescript
merge(...args: Object[]): Object
```

Merges two or more objects into a new one. The new object is without reference to the merged objects.
```js
Utils.Objects.merge({a: "1"}, {b: "2"}); // {a: "1", b: "2"}
Utils.Objects.merge({a: {b: "1"}}, {a: {c: "2"}}); // {a: {b: "1", c: "2"}}
```

```typescript
values(object: Object): any[]
```

Removes keys from provided object and returns its data.
Odstraní klíče daného objektu a vrátí jejich data.
```
Utils.Objects.values({a: "b", c: "d"}): // ["b", "d"]
```

## Strings (Utils.Strings)
```typescript
firstToUpper(string: string): string
```

Converts first letter of the given string to upper case.
```js
Utils.Strings.firstToUpper('test') // Test
```

```
generateHash(length: number, characters = 'abcdefghijklmnopqrstuvwxyz0123456789'): string
```

Generates hash from given characters and length.
Vytvoří hash o dané délce ze zadaných znaků.
```js
Utils.Strings.generateHash(32) // 32 characters long hash
```

```
sprintf(content: string, parameters: any[]): string
```

Replaces placeholders by given values.
```js
Utils.Strings.sprintf('%0% je %1%', ['Apicart', 'nejlepší']) // Apicart je nejlepší
Utils.Strings.sprintf('%spolecnost% je %hodnoceni%', {spolecnost: 'Apicart', hodnoceni: 'nejlepší'}) // Apicart je nejlepší
```

## Url (Utils.Url)
```typescript
getQueryParameter(name: string, url: string = (<any>window).location.href): string|null
```

Returns query parameter from the given url. If the parameter was not found, returns null.
```js
Utils.Url.getQueryParameter('number', 'https://example.com?number=1') // 1
```

## Validators (Utils.Validators)
```typescript
isEmpty(data: any): boolean
```

Returns true if the provided data are empty. Otherwise returns false.
```js
Utils.Validators.isEmpty([]) // true
Utils.Validators.isEmpty({}) // true
Utils.Validators.isEmpty('') // true
```

## Flash Messages (Utils.FlashMessages)

Flash messages allows you to persist messages through redirects.

```typescript
addMessage(content: any, type: string | null = null): this
```

Adds message. You can provide a custom type.
```js
Utils.FlashMessages.addMessage('Text');
Utils.FlashMessages.addMessage('Warning!', 'warning');
```

```typescript
getMessages(): Object
```

Returns messages.
```js
Utils.FlashMessages.getMessages();
```

```typescript
hasMessages(type: string | null = null): boolean
```

Returns true if there are some persisted messages.
```js
Utils.FlashMessages.hasMessages();
```

```typescript
 processMessages(callback: Function, type: string | null = null): this
```

Iterates over messages. If the type is set, the iteration is done only over the messages of the given type.
```js
Utils.FlashMessages.processMessages(function (message, type) { ... }); // Processes all messages
Utils.FlashMessages.processMessages(function (message, typ) { ... }, 'info'); // Processes only the info messages
```
