Skip to content
/ hlp Public

⛏️ Collection of string related functions in js. ⛏️

Notifications You must be signed in to change notification settings

vielhuber/hlp

Repository files navigation

build status

motivation

tired of writing

if( Object.keys(obj).length === 0 && obj.constructor === Object )
{

}

or

if (typeof arr !== 'undefined' && arr.length > 0)
{

}

or

for(const [obj__key, obj__value] of Object.entries(obj))
{

}

?

installation

npm init -y
npm install hlp

now use it as a module:

import hlp from 'hlp';

or embed it directly:

<script src="hlp.js"></script>

usage

existence

// check existence
if( hlp.x(vrbl) )
{

}

// check non-existence
if( hlp.nx(vrbl) )
{

}

equality

// js has a lot of pitfalls, when comparing loosely
if( '' == [] ) // true
if( '' == [''] ) // true
if( '' == 0 ) // true
if( ' ' == false ) // true
if( [0] == false ) // true
if( [0] == '0' ) // true
if( [] == false ) // true
if( [''] == false ) // true
if( 0 == false ) // true
if( 0 == [] ) // true
if( 0 == [''] ) // true
if( [0] == false ) // true
if( [0] == 0 ) // true

// also don't forget those delicacies
0 === -0 // true
NaN === NaN // false
(![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]] === 'fail' // true

// this non-strict equality is symmetric, but not transitive
a = ''; b = 0; c = [0];
a == b; // true
b == c; // true
c == a; // false

// to overcome this issue, we...

// ...use strict comparison when possible
if( vrbl === 'foo' )
{

}

// ...use loose comparison when appropriate
if( hlp.getParam('number') == 1337 )
{

}

// ...check for truthness / falsiness with these helper methods
if( hlp.true(vrbl) )
{

}

if( hlp.false(vrbl) )
{

}

// be aware, that hlp.true is not always the logic negation of hlp.false
hlp.true(null) // false
hlp.false(null) // false

value

// get variable if exists, otherwise ''
hlp.v( vrbl )

// get variable if exists, otherwise 'default'
hlp.v( vrbl, 'default' )

// get first variable that exists, otherwise ''
hlp.v( vrbl1, vrbl2, vrbl3 )

loop

// loop over arrays/objects only if possible
hlp.loop(['foo','bar','baz'], (vrbl__value) =>
{

});
hlp.loop(['foo','bar','baz'], (vrbl__value, vrbl__key) =>
{

});
hlp.loop({bar: 'foo', baz: 'bar', foo: 'baz'}, (vrbl__value, vrbl__key) =>
{

});
hlp.loop([], (vrbl__value, vrbl__key) => { }) // does nothing
hlp.loop({}, (vrbl__value, vrbl__key) => { }) // does nothing
hlp.loop(null, (vrbl__value, vrbl__key) => { }) // does nothing

try

// if you are unsure, if a variable is even set before checking its existence,
// simply put it inside this helper function
if( hlp.x(() => vrbl) )
if( hlp.nx(() => vrbl)  )
if( hlp.true(() => vrbl) )
if( hlp.false(() => vrbl)  )
if( hlp.v(() => vrbl) === 'foo' )
if( hlp.v(() => vrbl) == 1337 )
echo hlp.v(() => vrbl)
hlp.loop((() => vrbl), (vrbl__value, vrbl__key) => { })

that works because javascript only evaluates the content of the inner callback (or closure) when it is actually executed.

helpers

there are also some other neat little helpers available:

// capitalize
hlp.capitalize('foo') // Foo

// check if object
hlp.isObject({}) // true
hlp.isObject({foo: 'bar'}) // true
hlp.isObject(null) // false
hlp.isObject([]) // false (be aware: an array in js is scrictly an object, but this function returns false)

// check if array
hlp.isArray([]) // true
hlp.isArray(['foo','bar']) // true
hlp.isArray(null) // false

// check if string
hlp.isString('foo'); // true
hlp.isString(42); // false
hlp.isString(null); // false

// check if date
hlp.isDate('2018-01-01') // true
hlp.isDate('2018-02-29') // false
hlp.isDate('1700-01-01') // true
hlp.isDate(42) // false

// format date
hlp.formatDate('d.m.Y', '2018-01-01') // 01.01.2018
hlp.formatDate('Y-m-d H:i:s', new Date()) // 01.01.2018

// get week number from date
hlp.dateToWeek(new Date('2021-02-22')) // 8
hlp.dateToWeek() // hlp.dateToWeek(new Date())

// get date (of monday) from week number
hlp.weekToDate(42, 2018) // new Date('2018-10-14')
hlp.weekToDate(17, 2023) // new Date('2023-04-23')

// add days to date
hlp.addDays(new Date('2018-01-01'), 7) // new Date('2018-01-08')
hlp.addDays(new Date('2018-02-22'), 658) // new Date('2019-12-12')
hlp.addDays(new Date('2018-02-22'), 1) // new Date('2018-02-21')

// compare dates
let d1 = new Date();
let d2 = new Date();
hlp.compareDates(d1, d2) // 0
hlp.addDays(d1, -1);
hlp.compareDates(d1, d2) // -1
hlp.addDays(d1, 2);
hlp.compareDates(d1, d2) // 1
hlp.compareDates('2020-01-01', '2020-01-17 17:42:19') // -1

// format number
hlp.formatNumber(1337.427, 2, ',','.') // 1.337,43

// spaceship operator
hlp.spaceship(5,7) // -1
hlp.spaceship(9,7) // 1
hlp.spaceship(7,7) // 0
hlp.spaceship('foo','bar') // 1
hlp.spaceship('bar','foo') // -1

// check if objects are equal
hlp.objectsAreEqual({}, {}) // true
hlp.objectsAreEqual({ foo: 'bar' }, { foo: 'bar'}) // true
hlp.objectsAreEqual({ foo: 'bar' }, { bar: 'baz'}) // false

// check if object is inside an array/object
hlp.containsObject({ foo: 'bar' }, []) // false
hlp.containsObject({ foo: 'bar' }, [{ foo: 'bar' }, { bar: 'baz' }]) // true
hlp.containsObject({ foo: 'bar' }, { foo: { foo: 'bar' } }) // true

// recursively search key/value in nested object and return dotprop array
hlp.findRecursiveInObject({ foo: { id: 42 }, bar: { foo: { id: 7 } }, baz: { id1: 42, id2: 7 } }, 'id'); // ['foo', 'bar.foo']
hlp.findRecursiveInObject({ foo: { id: 42 }, bar: { foo: { id: 7 } }, baz: { id1: 42, id2: 7 } }, 'id', 42); // ['foo']
hlp.findRecursiveInObject({ foo: { id: 42 }, bar: { foo: { id: 7 } }, baz: { id1: 42, id2: 7 } }, null, 7); // ['bar.foo', 'baz']

// deep clone reference types (object/array/date/regex)
hlp.deepCopy({ foo: 'bar' })
hlp.deepCopy(['foo','bar'])
hlp.deepCopy(new Date())
hlp.deepCopy(new Date('2018-01-01'))
hlp.deepCopy(new RegExp('ab+c', 'i'))

// generate uuid/guid v4
hlp.uuid() // e86e393c-9788-857b-27c2-f80c8ca1a302
hlp.uuid() // 8b25a8f8-9525-bd73-4679-3539321db93b

// replace all occurences
hlp.replaceAll('foo bar baz', 'a', 'b') // 'foo bbr bbz'

// replace last occurence
hlp.replaceLast('foo bar baz', 'a', 'b') // 'foo bar bbz'

// replace last occurence
hlp.replaceFirst('foo bar baz', 'a', 'b') // 'foo bbr baz'

// case insensitive search
hlp.indexOfCaseInsensitive('foo', 'this is a FOO') // 10
hlp.indexOfCaseInsensitive('foo', 'this is a FOO and a foobar', 15) // 20

// count occurences in string
hlp.countAllOccurences('foo', 'this is a foo and a foobar') // 2
hlp.countAllOccurencesCaseInsensitive('FoO', 'this is a FOO and a foobar') // 2

// find all positions in string
hlp.findAllPositions('foo', 'this is a foo and a foobar') // [10,20]
hlp.findAllPositionsCaseInsensitive('FoO', 'this is a FOO and a foobar') // [10,20]

// highlight strings
hlp.highlight('that is a search string', 'is') // that <strong class="highlight">is</strong> a search string
hlp.highlight('abc def geh ijk lmn opq rst abc def geh ijk lmn opq rst', 'ijk', true, 5) // '... geh <strong class="highlight">ijk</strong> lmn ... geh <strong class="highlight">ijk</strong> lmn ...'

// remove empty elements from array
hlp.removeEmpty(['foo',null,[],'','bar']) // ['foo','bar']

// return unique array (remove duplicate values, order-safe)
hlp.uniqueArray(['foo','bar','foo','baz']) // ['foo','bar','baz']

// powerset of array (all subsets of a set)
hlp.powerset([1,2,3]) // [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

// shuffle array
hlp.shuffle(['foo','bar']) // ['foo','bar']
hlp.shuffle(['foo','bar']) // ['foo','bar']
hlp.shuffle(['foo','bar']) // ['foo','bar'] (yikes)
hlp.shuffle(['foo','bar']) // ['bar','foo']

// char helpers
hlp.charToInt('D') // 4
hlp.intToChar(4) // 'D'
hlp.incChar('D') // 'E'
hlp.incChar('Z') // 'AA'
hlp.incChar('A',2) // 'C'
hlp.decChar('U') // 'T'

// slugify / sanitize string
hlp.slugify('That röcks!') // that-roecks

// range
hlp.range('A','Z') // ['A','B',...,'Z']
hlp.range(1,42) // [1,2,...,42]
hlp.range('C','A') // ['C','B','A']

// get last item of object/array
hlp.last(['foo', 'bar', 'baz']) // 'baz'
hlp.last({ foo: 'bar', bar: 'baz'}) // 'baz'

// get first item of object/array
hlp.first(['foo', 'bar', 'baz']) // 'foo'
hlp.first({ foo: 'bar', bar: 'baz'}) // 'bar'

// get random element from object/array
hlp.rand(['foo', 'bar', 'baz']) // 'bar'

// generate a random string
hlp.random_string() // edPhi34d
hlp.random_string(10) // abCa321aC6
hlp.random_string(16, 'idkfa') // idifafafifaifafk

// generate a random integer
hlp.random_int() // 42
hlp.random_int(7,42) // 17

// proper rounding to n digits
hlp.round(1.005, 2) // 1.01
hlp.round(1.005) // 1

// check if variable is integer
hlp.isInteger('foo') // false
hlp.isInteger(42) // true
hlp.isInteger('42') // true
hlp.isInteger(4e2) // true
hlp.isInteger('4e2') // true
hlp.isInteger(' 1 ') // true
hlp.isInteger('') // false
hlp.isInteger('  ') // false
hlp.isInteger(42.1) // false
hlp.isInteger('1a') // false
hlp.isInteger('4e2a') // false
hlp.isInteger(null) // false
hlp.isInteger(undefined) // false
hlp.isInteger(NaN) // false

// check if variable is numeric
hlp.isNumeric(1337) // true
hlp.isNumeric('42') // true
hlp.isNumeric('42.7') // true
hlp.isNumeric('a') // false

// json parsing
hlp.jsonStringToObject('["foo","bar","baz"]') // ['foo','bar','baz']
hlp.jsonStringToObject('["foo","bar","baz",]') // null
hlp.jsonObjectToString(['foo','bar','baz']) // '["foo","bar","baz"]'
hlp.isJsonString('["foo","bar","baz",]') // false
hlp.isJsonString('["foo","bar","baz"]') // true

// map for objects
hlp.map({ foo: 'bar', bar: 'baz' }, (obj__key, obj__value) => obj__value += '!'); // { foo: 'bar!', bar: 'baz!' }

// fun with blobs
hlp.stringtoblob(string)
hlp.stringtoblob(string, 'image/png')
hlp.blobtostring(blob).then((string) => { })
hlp.blobtobase64(blob).then((base64) => { })
hlp.base64toblob(base64)
hlp.base64toblob(base64, 'image/png')
hlp.filetobase64(file).then((base64) => { })
hlp.blobtofile(blob)
hlp.blobtofile(blob, 'filename.png')
hlp.filetoblob(file)
hlp.base64tofile(base64)
hlp.base64tofile(base64, 'image/png')
hlp.base64tofile(base64, 'image/png', 'filename.png')
hlp.base64tostring(base64)
hlp.stringtobase64(string)
hlp.blobtourl(blob)
hlp.stringtourl(string)
hlp.base64tourl(base64)
hlp.filetourl(file)

// fix exif image orientation
hlp.fixImageOrientation(base64).then((base64) => { });
hlp.getImageOrientation(base64).then((orientation) => { });

// html entity encode/decode
hlp.htmlEncode('&<>"`\'') // &amp;&lt;&gt;&quot;&#96;&#x27;
hlp.htmlDecode('&amp;&lt;&gt;&quot;&#96;&#x27;') // &<>"`'

// line break conversion
hlp.nl2br('foo\nbar') // foo<br/>bar
hlp.br2nl('foo<br/>bar') // foo\nbar

// floating point math made easy
hlp.fmath('*', 0.1, 0.2) // 0.02
hlp.fmath('+', 0.1, 0.2) // 0.3
hlp.fmath('-', 0.1, 0.2) // -0.1
hlp.fmath('/', 0.2, 0.1) // 2
hlp.fmath('/', 0.39, 100, 12) // 0.0039 (precision of 12)

// trim helpers
hlp.trim('  foo ') // 'foo'
hlp.trim('xxfoox', 'x') // 'foo'
hlp.ltrim('  foo ') // 'foo '
hlp.ltrim('xxfoox', 'x') // 'foox'
hlp.rtrim('  foo ') // '  foo'
hlp.rtrim('xxfoox', 'x') // 'xxfoo'

// truncate/trim long strings
hlp.truncate_string('Lorem ipsum dolor sit amet, consectetuer.', 20); // Lorem ipsum dolor ...
hlp.truncate_string('Lorem ipsum dolor sit amet, consectetuer.', 20, '…'); // Lorem ipsum dolor …

// fun with emojis
let str = 'This❤️😀👩‍⚖️ is a text full of 🧗‍♀️emojis👩🏼‍❤️‍💋‍👩🏽.';
str.match(hlp.emojiRegex()) // ['❤️', '😀', '👩‍⚖️', '🧗‍♀️', '👩🏼‍❤️‍💋‍👩🏽']
str.replaceAll(hlp.emojiRegex(), '') // This is a text full of emojis.
str.replace(hlp.emojiRegex(false), '') // This😀👩‍⚖️ is a text full of 🧗‍♀️emojis👩🏼‍❤️‍💋‍👩🏽.
hlp.emojiRegex().test(str) // true

// create lexicographically ordered string ids like in firebase
hlp.pushId() // -LDiDooGs9PyGHmghk5i
hlp.pushId() // -LDiDooGs9PyGHmghk5j

// access object properties with dotprop notation
// today it is better to use optional chaining in combination with nullish coalescing ({}?.c?.a?.a??'default')
hlp.getProp({
    a: 1,
    b: { a: 3, b: 3 },
    c: { a: { a: 7 } }
}, 'c.a.a') // 7

check out also the following helpers for the frontend:

// cookies
hlp.cookieSet('foo', 'bar', 7)
hlp.cookieSet('foo', 'bar', 7, false) // only for current domain (no subdomains)
hlp.cookieGet('foo') // bar
hlp.cookieDelete('foo')
hlp.cookieDelete('foo', false) // only for current domain (no subdomains)
hlp.cookieExists('foo') // true|false

// localstorage (with expiration time and object support)
hlp.localStorageSet('foo', {some: 'data'}, 7)
hlp.localStorageGet('foo') // {'some': 'data'}
hlp.localStorageDelete('foo')
hlp.localStorageExists('foo') // true|false

// get parameter (example url: https://tld.com/?foo=bar&bar=baz)
hlp.getParam('foo') // foo
hlp.getParam('bar') // baz
hlp.getParam('baz') // null

// device detection helpers
hlp.getDevice() // ['phone','tablet','desktop']
hlp.isPhone()
hlp.isTablet()
hlp.isDesktop()
hlp.isMobile()
hlp.isTouch()

// os detection helpers
hlp.getOs() // ['windows','mac','linux','unknown']
hlp.isWindows()
hlp.isMac()
hlp.isLinux()

// browser detection helpers
hlp.getBrowser() // ['ie','edge','firefox','chrome','safari','opera','unknown']

// smooth scroll to position / element
hlp.scrollTo( 0, 1000 ).then(() => { console.log('done'); });
hlp.scrollTo( document.querySelector('.foo'), 1000 ).then(() => { console.log('done'); });
hlp.scrollTo( 0, 1000, document.querySelector('.bar') ).then(() => { console.log('done'); }); // scoll inside .bar
hlp.scrollTo( document.querySelector('.foo'), 1000, null, -200 ).then(() => { console.log('done'); }); // apply offset
hlp.scrollTo( document.querySelector('.foo'), 1000, null, document.querySelector('.header') ).then(() => { console.log('done'); }); // apply offset (height of dom element only if it exists and is fixed!)
hlp.scrollTo( document.querySelector('.foo'), 1000, null, [document.querySelector('.header'), -200] ).then(() => { console.log('done'); }); // you can also provide multiple values (of different type)
hlp.scrollTo( document.querySelector('.foo'), 1000, null, -200, true ).then(() => { console.log('done'); }); // only scroll up (never down)

// get top/left scroll position
hlp.scrollTop()
hlp.scrollLeft()

// get closest vertical scrollable element (including oneself)
hlp.closestScrollable( document.querySelector('.foo') )

// get offset of element (excluding margin)
hlp.offsetTop( document.querySelector('.foo') )
hlp.offsetLeft( document.querySelector('.foo') )
hlp.offsetRight( document.querySelector('.foo') )
hlp.offsetBottom( document.querySelector('.foo') )

// get offset of element (including margin)
hlp.offsetTopWithMargin( document.querySelector('.foo') )
hlp.offsetLeftWithMargin( document.querySelector('.foo') )
hlp.offsetRightWithMargin( document.querySelector('.foo') )
hlp.offsetBottomWithMargin( document.querySelector('.foo') )

// get document size
hlp.documentWidth()
hlp.documentHeight()

// get window size
hlp.windowWidth()
hlp.windowHeight()
hlp.windowWidthWithoutScrollbar()
hlp.windowHeightWithoutScrollbar()

// get width with margin
hlp.outerWidthWithMargin( document.querySelector('.foo') )
hlp.outerHeightWithMargin( document.querySelector('.foo') )

// get cursor position (without mouse events)
hlp.cursorPosition().then(pos => { console.log(pos); /* pos: { x: ..., y: ... } */ });

// polyfills for ie11
hlp.closest( document.querySelector('.children'), '.parent' )
hlp.matches( document.querySelector('.parent'), '.parent' ) // true
hlp.remove( document.querySelector('.foo') ) // also works if .foo does not exist

// dom traversal
hlp.prevAll( document.querySelector('.foo') )
hlp.prevAll( document.querySelector('.foo'), '.bar' )
hlp.nextAll( document.querySelector('.foo') )
hlp.nextAll( document.querySelector('.foo'), '.bar' )
hlp.siblings( document.querySelector('.foo') )
hlp.siblings( document.querySelector('.foo'), '.bar' )
hlp.parents( document.querySelector('.foo') )
hlp.parents( document.querySelector('.foo'), '.bar' )
hlp.prevUntil( document.querySelector('.foo'), '.bar' ) // prev until selector not including
hlp.nextUntil( document.querySelector('.foo'), '.bar' ) // next until selector not including
hlp.prev( document.querySelector('.foo') )
hlp.prev( document.querySelector('.foo'), '.bar' )
hlp.next( document.querySelector('.foo') )
hlp.next( document.querySelector('.foo'), '.bar' )

// wrap element
hlp.wrap( document.querySelector('.foo'), '<div class="wrapper"></div>' )

// wrap all text nodes with new node
hlp.wrapTextNodes( document.querySelector('.foo'), 'p' )

// html string to dom (also supports ie11 and td nodes that cannot be root nodes)
hlp.html2dom('<p>foo</p>')
hlp.html2dom('<td>bar</td>')

// get all styles of a dom element (extracted from both inline styling and external styling through stylesheets)
hlp.css( document.querySelector('.foo') )

// visually focus element on page
hlp.focus('.foo')
hlp.focus(document.querySelector('.foo'))
hlp.unfocus()

// on delegate
hlp.on('click', '.selector', (e, el) => { });
hlp.on('click', '.selector', '.scope', (e, el) => { });

// classic debounce
window.addEventListener('resize', hlp.debounce(() => { console.log('debounce at resize') }, 1000));
document.querySelector('.container').addEventListener('input', hlp.debounce((e) => { console.log('debounce at '+e.target.value); }, 1000));
let debounce = hlp.debounce((e) => { console.log('debounce at '+e.target.value); }, 1000); // conditional debounce
document.querySelector('.container').addEventListener('input', e => { debounce(e); });

// classic throttle
window.addEventListener('resize', hlp.throttle(() => { console.log('throttle at resize') }, 1000));
document.querySelector('.container').addEventListener('input', hlp.throttle((e) => { console.log('throttle at '+e.target.value); }, 1000));
let throttle = hlp.throttle((e) => { console.log('throttle at '+e.target.value); }, 1000); // conditional throttle
document.querySelector('.container').addEventListener('input', e => { throttle(e); });

// get current url
hlp.url() // https://github.com/vielhuber/hlp
hlp.urlWithHash() // https://github.com/vielhuber/hlp#foo
hlp.fullUrl() // https://github.com/vielhuber/hlp?foo=bar#foo
hlp.urlWithArgs() // https://github.com/vielhuber/hlp?foo=bar
hlp.baseUrl() // https://github.com
hlp.urlHost(); // github.com
hlp.urlHostTopLevel(); // github.com
hlp.urlPath(); // /vielhuber/hlp
hlp.urlHash(); // #foo
hlp.urlArgs(); // ?foo=bar

// get url of current running script
hlp.urlOfScript(); // https://tld.com/wp-content/themes/dummy/script.js
hlp.pathOfScript(); // https://tld.com/wp-content/themes/dummy

// set 100vh for a dom element (respecting the visibility of the address bar)
hlp.real100vh('.foo') // 100vh
hlp.real100vh('.foo', 60) // 60vh
hlp.real100vh() // sets up a css variable which can be used with e.g. calc(100 * var(--vh, 1vh)); to mimic 100vh

// remove hover states on ios to prevent double clicks (see https://stackoverflow.com/questions/47802530/a-click-in-ios-safari-triggers-a-hover-state-on-element-underneath-where-you-t);
hlp.iOsRemoveHover();

// fade in/out dom element
hlp.fadeIn( document.querySelector('.foo'), 1000 ).then(() => { console.log('done'); });
hlp.fadeOut( document.querySelector('.foo'), 1000 ).then(() => { console.log('done'); });

// check if dom element is generally visible
hlp.isVisible( document.querySelector('.foo') )
// check if dom element is visible inside viewport
hlp.isVisibleInViewport( document.querySelector('.foo') )

// wait until a dom element has a certain css property
// this is quite useful when working with async loaded stylesheets like loadCSS
// .beacon is an element below the fold populated by the stylesheet
hlp.waitUntil('.beacon').then(() => { });
hlp.waitUntil('.beacon','position').then(() => { });
hlp.waitUntil('.beacon','position','relative').then(() => { });

// wait until a variable is set or has a specific value
hlp.waitUntilVar('globalVar').then(() => { });
hlp.waitUntilVar(obj, 'objectVar').then(() => { });
hlp.waitUntilVar(obj, 'objectVar', true).then(() => { });

// run a function for every dom element, even it is added dynamically later on
hlp.runForEl('.beacon', el => { el.style.backgroundColor = 'red'; });

// automatically change height of all textareas based on content
hlp.textareaAutoHeight()
hlp.textareaAutoHeight('.special')
hlp.textareaSetHeight( document.querySelector('.special') )

// load external js file in dom with promise
hlp.loadJs('https://apis.google.com/js/api.js').then(() => { console.log('done'); });
hlp.loadJs([
    'https://www.tld.com/1.js',
    'https://www.tld.com/2.js',
    'https://www.tld.com/3.js'
]).then(() => { console.log('done'); });
hlp.loadJsSequentially([
    'https://www.tld.com/1.js',
    'https://www.tld.com/2.js',
    'https://www.tld.com/3.js'
]).then(() => { console.log('done'); });

// run event after all images are loaded inside container
// works even after dynamic changes
// runs more than once (after each change)
// run this outside of window load / document ready events
hlp.triggerAfterAllImagesLoaded('.container', '.container__image', () => {});

// proper document read/load events, that are guaranteed to be run (also if the script is embedded via async)
hlp.ready().then(() => {});
hlp.load().then(() => {});

// easy ajax requests (without the fetch api; also works in ie11)
hlp.get('https://httpbin.org/anything').then((response) => { }).catch((error) => { }) // { "method": "GET", ... }
hlp.get('/relpath').then((response) => { }).catch((error) => { }) // if a full url is omitted, the call is done on the baseurl
hlp.get('https://httpbin.org/anything', { throttle: 1000 }).then((response) => { }).catch((error) => { }) // same but with a throttle of 1 second
hlp.get('https://httpbin.org/status/404', { allow_errors: false }).then((response) => { }) // deny 404 and other status codes as a response (inside catch())
hlp.post('https://httpbin.org/anything', { data: { foo: 'bar' } }).then((response) => { }).catch((error) => { }) // { "method": "POST", "data": {"foo": "bar"}, ... }
hlp.post('https://httpbin.org/anything', { data: { foo: 'bar' }, headers: { Bar: 'baz' } }).then((response) => { }).catch((error) => { }) // { "method": "POST", "headers" = { "Bar": "baz", ... }, ... }
let formData = new FormData(); formData.append('foo', 'bar'); hlp.post('https://httpbin.org/anything', { data: formData }) // this also works with FormData

// on resize vertically/horizontally
window.addEventListener('resize', () => {}) // inaccurate, triggers too often (especially when scrolling on android/iphone)
hlp.onResizeHorizontal(() => {}) // only triggers when viewport width changes; also triggers on first run
hlp.onResizeVertical(() => {}) // only triggers when viewport height changes; also triggers on first run

// add event listener once
hlp.addEventListenerOnce(
    document.getElementById('foo'),
    'click',
    (event) => { alert('this gets called only once'); }
);
hlp.addEventListenerOnce(
    document.getElementById('foo'),
    'click',
    (event) => { if(1==1) { return false; } } // if you return false, the event listener is not removed
);

// simple animations (via css transitions)
hlp.animate(
    document.getElementById('.single'),
    'transform: translateX(0)',
    'transform: translateX(-100%)',
    'ease-in-out',
    1000
).then(() => { console.log('done'); });
hlp.animate(
    document.querySelectorAll('.multiple'),
    'opacity: 1; pointer-events:auto',
    'opacity: 0; pointer-events:none',
    'linear',
    5000
).then(() => { console.log('done'); });

php implementation

there is also a php implemenation stringhelper with similiar functions available.

appendix

existence matrix

hlp.x() hlp.true() hlp.false() !== null != null !== false != false === true == true typeof !== 'undefined' != undefined !== undefined if/else ternary length > 0 != '' !== ''
undefined false true false true false true true false false false false false false false error true true
null false false false false false true true false false true false true false false error true true
false false false true true true false false false false true true true false false false false true
true true true false true true true true true true true true true true true false true true
[] false false false true true true false false false true true true true true false false true
[''] false false false true true true false false false true true true true true true false true
0 true false true true true true false false false true true true false false false false true
1 true true false true true true true false true true true true true true false true true
-1 true true false true true true true false false true true true true true false true true
'0' true false true true true true false false false true true true true true true true true
'1' true true false true true true true false true true true true true true true true true
'-1' true true false true true true true false false true true true true true true true true
'' false false false true true true false false false true true true false false false false false
' ' false false false true true true false false false true true true true true true true true
'null' true false false true true true true false false true true true true true true true true
'false' true false true true true true true false false true true true true true true true true
'true' true true false true true true true false false true true true true true true true true
'str' true true false true true true true false false true true true true true true true true
[0,1] true true false true true true true false false true true true true true true true true
[0] true true false true true true false false false true true true true true true true true
{} false false false true true true true false false true true true true true false true true
un.known.property error error error error error error error error error error false false error error error error error
(()=>un.known.property) true true false true true true true false false true true true true true true true true

loose comparison matrix

== undefined null false true [] [''] 0 1 -1 '0' '1' '-1' '' ' ' 'null' 'false' 'true' 'str' [0,1] [0] {} un.known.property (()=>un.known.property)
undefined true true false false false false false false false false false false false false false false false false false false false error false
null true true false false false false false false false false false false false false false false false false false false false error false
false false false true false true true true false false true false false true true false false false false false true false error false
true false false false true false false false true false false true false false false false false false false false false false error false
[] false false true false true false true false false false false false true false false false false false false false false error false
[''] false false true false false true true false false false false false true false false false false false false false false error false
0 false false true false true true true false false true false false true true false false false false false true false error false
1 false false false true false false false true false false true false false false false false false false false false false error false
-1 false false false false false false false false true false false true false false false false false false false false false error false
'0' false false true false false false true false false true false false false false false false false false false true false error false
'1' false false false true false false false true false false true false false false false false false false false false false error false
'-1' false false false false false false false false true false false true false false false false false false false false false error false
'' false false true false true true true false false false false false true false false false false false false false false error false
' ' false false true false false false true false false false false false false true false false false false false false false error false
'null' false false false false false false false false false false false false false false true false false false false false false error false
'false' false false false false false false false false false false false false false false false true false false false false false error false
'true' false false false false false false false false false false false false false false false false true false false false false error false
'str' false false false false false false false false false false false false false false false false false true false false false error false
[0,1] false false false false false false false false false false false false false false false false false false true false false error false
[0] false false true false false false true false false true false false false false false false false false false true false error false
{} false false false false false false false false false false false false false false false false false false false false true error false
un.known.property error error error error error error error error error error error error error error error error error error error error error error error
(()=>un.known.property) false false false false false false false false false false false false false false false false false false false false false error true

About

⛏️ Collection of string related functions in js. ⛏️

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published