1.0.5 • Published 5 years ago

@nawawishkid/cloneable v1.0.5

Weekly downloads
1
License
MIT
Repository
github
Last release
5 years ago

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 just max
  • 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 to function 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.

nametypedefaultisRequiredexplanation
loadfunction[][] Empty arrayfalseArray of event listeners (callback function) for load event
beforeStateChangefunction[][] Empty arrayfalseArray of event listeners (callback functions) for beforeStateChange event
afterStateChangefunction[][] Empty arrayfalseArray of event listeners (callback functions) for afterStateChange event
uncloneablefunction[][] Empty arrayfalseArray of event listeners (callback functions) for uncloneable event

CloneableOptions

Object of options for Cloneable instance.

nametypedefaultisRequiredexplanation
maxCloneablenumberInfinityfalseMaximum number of cloned element
isAppendbooltruefalseWhether the cloned element will be append or prepend to the source element
cloneButtonHTMLElementnullfalseHTMLElement to be used as clone button
removeButtonHTMLElementnullfalseHTMLElement to be cloned and then used as remove button for each cloned element
middlewaresfunction[][] Empty arrayfalseArray of callback functions to be called with cloned element as an argument
eventsCloneableEvents{} Empty objectfalseCloneableEvents object

Instantiation

Cloneable(HTMLElement container, CloneableOptions options = {})

Instantiate cloneable object.

Parameters

nametypedefaultisRequiredexplanation
containerHTMLElementundefinedtrueAny HTMLElement that its firstElementChild will be cloned.
optionsCloneableOptions{} Empty objectfalseCloneableOptions 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

keytypeexplanation
containerHTMLElementContainer element.
middlewaresarrayArray of registered middlewares.
cloneButtonHTMLElementClone button element. An element, e.g. HTMLButtonElement, for triggering element cloning.
optionsCloneableOptionsCloneableOptions object of current Cloneable instance.
eventsCloneableEventsCloneableEvents 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:

  1. Create .tray element.
  2. Move firstElementChild of the given container (the source element to be cloned) to the .tray element.
  3. Create .controllers element.
  4. Get/create .clone-btn button then append to the .controllers element.
  5. 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

nametypedefaultisRequiredexplanation
idnumberundefinedtrueID 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

nametypedefaultisRequiredexplanation
callbackfunctionundefinedtrueMiddleware 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

nametypedefaultisRequiredexplanation
eventNamestringundefinedtrueEvent name. See available event at CloneableEvents.
eventListenerfunctionundefinedtrueEvent 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

typevaluewhen
booltrueNumber of cloned elements is less than maxCloneable value
boolfalseNumber 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

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago