@nawawishkid/cloneable
v1.0.5
Published
Make specific HTMLElement cloneable.
Downloads
3
Readme
Cloneable.js
Make specific HTMLElement cloneable via user interface e.g. <button>
element, or clone programmatically via JavaScript API.
TODO:
Improvements:
- [ ] Change option name from
maxCloneable
to justmax
- ~~[x] Remove button disability mechanism. If one prefers to disable button when number of cloned elements reach its maximum number allowed, use
uncloneable
event to disable it manually.~~ - [ ] Try changing from using
class
tofunction
to decrease bundle size. - [ ] Allow user to set default classname of the created elements e.g.
.tray
,.controllers
,.clone-btn
, or.remove-btn
.
Installation
NPM
npm i @nawawishkid/cloneable
CDN
On npm: https://cdn.jsdelivr.net/npm/@nawawishkid/cloneable@latest/dist/cloneable.min.js
On GitHub: https://cdn.jsdelivr.net/gh/nawawishkid/cloneable.js@latest/dist/cloneable.min.js
NPM Scripts
build
-- Build (bundle) this library.test
-- Run test suite.
Quick start
In your index.html
:
<div id="cloneable-container"><p>Clone me!</p></div>
<script src="src/index.js"></script>
In your src/index.js
:
// For NPM only
// import Cloneable from "@nawawishkid/cloneable.js"
const container = document.getElementById("cloneable-container");
const cloneable = new Cloneable(container);
cloneable.init();
Now the #cloneable-container
will be like:
<div id="cloneable-container">
<div class="tray">
<p>Clone me!</p>
<div class="cloned" data-cloned-id="1">
<p>Clone me!</p>
<button class="remove-btn">Remove</button>
</div>
</div>
<div class="controllers"><button class="clone-btn">Clone</button></div>
</div>
Now, you can click .clone-btn
button to clone <p>Clone me!</p>
or clicking .remove-btn
button to remove cloned element.
API
Types
CloneableEvents
Object of events that Cloneable
accepts.
| name | type | default | isRequired | explanation |
| ------------------- | ------------ | ---------------- | ---------- | --------------------------------------------------------------------------- |
| load
| function[]
| []
Empty array | false
| Array of event listeners (callback function) for load
event |
| beforeStateChange
| function[]
| []
Empty array | false
| Array of event listeners (callback functions) for beforeStateChange
event |
| afterStateChange
| function[]
| []
Empty array | false
| Array of event listeners (callback functions) for afterStateChange
event |
| uncloneable
| function[]
| []
Empty array | false
| Array of event listeners (callback functions) for uncloneable
event |
CloneableOptions
Object of options for Cloneable
instance.
| name | type | default | isRequired | explanation |
| -------------- | ----------------- | ----------------- | ---------- | --------------------------------------------------------------------------------- |
| maxCloneable
| number
| Infinity
| false
| Maximum number of cloned element |
| isAppend
| bool
| true
| false
| Whether the cloned element will be append or prepend to the source element |
| cloneButton
| HTMLElement
| null
| false
| HTMLElement
to be used as clone button |
| removeButton
| HTMLElement
| null
| false
| HTMLElement
to be cloned and then used as remove button for each cloned element |
| middlewares
| function[]
| []
Empty array | false
| Array of callback functions to be called with cloned element as an argument |
| events
| CloneableEvents
| {}
Empty object | false
| CloneableEvents
object |
Instantiation
Cloneable(HTMLElement container, CloneableOptions options = {})
Instantiate cloneable object.
Parameters
| name | type | default | isRequired | explanation |
| ----------- | ------------------ | ----------------- | ---------- | -------------------------------------------------------------- |
| container
| HTMLElement
| undefined
| true
| Any HTMLElement
that its firstElementChild
will be cloned. |
| options
| CloneableOptions
| {}
Empty object | false
| CloneableOptions
object |
Example
const options = {
maxCloneable: 10,
isAppend: false,
cloneButton: document.querySelector(".my-clone-button"),
removeButton: document.querySelector(".my-remove-button")
};
const container = document.getElementById("cloneable-container");
const cloneable = new Cloneable(container, options);
Properties
| key | type | explanation |
| ------------- | ------------------ | ----------------------------------------------------------------------------------------- |
| container
| HTMLElement
| Container element. |
| middlewares
| array
| Array of registered middlewares. |
| cloneButton
| HTMLElement
| Clone button element. An element, e.g. HTMLButtonElement, for triggering element cloning. |
| options
| CloneableOptions
| CloneableOptions
object of current Cloneable
instance. |
| events
| CloneableEvents
| CloneableEvents
object of current Cloneable
instance. |
Methods
Cloneable.init()
Initialize manipulation of given container element.
Note: You can't clone element without calling this method first.
This method will:
- Create
.tray
element. - Move
firstElementChild
of the given container (the source element to be cloned) to the.tray
element. - Create
.controllers
element. - Get/create
.clone-btn
button then append to the.controllers
element. - Append the
.tray
and.controllers
elements to the given container.
Return
this
Example
// Nothing in document changes at this point
const cloneable = new Cloneable(container);
// DOM manipulated! Ready to clone element.
cloneable.init();
Cloneable.clone()
Clone the element programmatically.
Clone the element, wrap it with wrapper element, then inject them into the given container element. The wrapper element has been assigned data-cloned-id
attribute so that it can be refered to later e.g. used by Cloneable.removeClonedElement()
method.
Return
this
Cloneable.removeClonedElement(Number id)
Remove the cloned element programmatically.
Remove cloned element with specified ID. Cloned element ID is a sequential number of cloning order. The first cloned element's ID is 1, the second is 2, and so on.
This method will find element using Cloneable.tray.querySelector('[data-cloned-id="${id}"]')
then remove it.
Parameters
| name | type | default | isRequired | explanation |
| ---- | -------- | ----------- | ---------- | ---------------------------------- |
| id
| number
| undefined
| true
| ID of cloned element to be removed |
Return
this
Example
const cloneable = new Cloneable(container);
// Clone element 2 times. Now, we have 2 cloned elements.
cloneable
.init()
.clone()
.clone();
// Remove first cloned element. Now, there is only 1 cloned element.
cloneable.removeClonedElement(1);
Cloneable.middleware(...callbacks)
Register middleware function to be called with cloned element as an argument. Use to alter the cloned element.
This method accepts argument list.
Parameters
| name | type | default | isRequired | explanation |
| ---------- | ---------- | ----------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------- |
| callback
| function
| undefined
| true
| Middleware function which accepts the cloned element as the first argument and cloned element's index or ID as a second argument |
Return
this
Example
Change textContent
of the cloned element.
const cloneable = new Cloneable(container);
cloneable
.middleware((cloned, index) => {
cloned.textContent = `Cloned #${index}`;
return cloned;
})
.init();
Cloneable.on(String eventName, ...eventListener)
Add event listener to the Cloneable
object. Similar to Node.js EventEmitter
class.
This method accepts argument list.
Parameters
| name | type | default | isRequired | explanation |
| --------------- | ---------- | ----------- | ---------- | --------------------------------------------------------------- |
| eventName
| string
| undefined
| true
| Event name. See available event at CloneableEvents
. |
| eventListener
| function
| undefined
| true
| Event listener callback function to be called on event occurred |
Return
this
Example
const cloneable = new Cloneable(container);
cloneable.on("beforeStateChange", () => {
console.log("State is gonna change!");
});
cloneable.init();
Cloneable.isCloneable()
Check if it's still cloneable.
Return
| type | value | when |
| ------ | ------- | -------------------------------------------------------------------------- |
| bool
| true
| Number of cloned elements is less than maxCloneable
value |
| bool
| false
| Number of cloned elements is greater than or equal to maxCloneable
value |
Example
const cloneable = new Cloneable(container, { maxCloneable: 2 });
cloneable.init();
cloneable.clone().isCloneable(); // -> true
cloneable.clone().isCloneable(); // -> false