import { addElement } from 'sesajs/dom'
/** @module editGraphe/fonctionsUtiles */
/**
* Retourne la position absolue d’un élément html
* @param {Element} el
* @returns {{x: number, y: number}}
*/
export function findPosDiv (el) {
let x = 0
let y = 0
if (el.offsetParent) {
x = el.offsetLeft
y = el.offsetTop
while (el === el.offsetParent) {
x += el.offsetLeft
y += el.offsetTop
}
}
return { x, y }
}
/**
* Alias de getElementById
* @param {string} id
* @returns {Element}
*/
export function gettag (id) {
return document.getElementById(id)
}
export function clone (srcInstance) {
/* Si l’instance source n’est pas un objet ou qu’elle ne vaut rien c’est une feuille donc on la retourne */
if (typeof srcInstance !== 'object' || srcInstance == null) {
return srcInstance
}
/* On appelle le constructeur de l’instance source pour crée une nouvelle instance de la même classe */
const newInstance = srcInstance.constructor()
/* On parcourt les propriétés de l’objet et on les recopies dans la nouvelle instance */
for (const i in srcInstance) {
newInstance[i] = clone(srcInstance[i])
}
/* On retourne la nouvelle instance */
return newInstance
}
/**
* Configuration d’un élément html à créer
* @typedef EltConfig
* @property {string} [id] id html de l’élément à créer
* @property {HTMLElement} [papa] Le parent dans lequel ajouter l’élément créé (en dernier)
*/
/**
* Ajoute l’élément défini par config à config.papa
* @param {EltConfig} config
* @return {HTMLElement}
*/
export function addElt (config) {
if (!config.papa) {
console.error('config sans papa', config)
throw Error('impossible d’ajouter un élément sur un objet sans parent')
}
const elt = getElt(config)
if (!elt) throw Error('Pas trouvé l’élément à ajouter')
config.papa.appendChild(elt)
return elt
}
export function getElt (config) {
if (typeof config !== 'object' || typeof config.tag !== 'string') throw Error('paramètres invalides')
const elt = document.createElement(config.tag)
if (config.id) elt.id = config.id
if (config.fontSize) elt.style.fontSize = config.fontSize
if (config.color) elt.style.color = config.color
return elt
}
/**
* Retourne un élément du dom, le crée s’il n’existait pas
* @param {HTMLElement} parent
* @param {string} tag
* @param {object} options
* @param {string} [options.id]
* @param {string} [options.className] Si pas d’id fourni il faut fournir une classe css, ce sera le premier élément (avec le bon tag) de parent ayant cette classe qui sera retourné
* @param {string} [childText]
* @return {HTMLElement}
*/
export const findOrCreateElement = (parent, tag, { id, className }, childText) => {
if (id) {
return document.getElementById(id) || addElement(parent, tag, { id, content: childText })
}
if (className) {
let elt
const elts = parent.getElementsByClassName(className)
if (elts && elts.length) {
// on prend le premier avec le bon tag
elts.some(_elt => {
if (_elt.tagName === tag) {
elt = _elt
return true // pour arrêter la boucle
}
return false
})
}
if (elt) return elt
return addElement(parent, tag, { class: className, content: childText })
}
throw Error('Paramètres incorrect (il faut fournir id ou className en option')
}
/**
* Ajoute un <div> dans config.papa
* @param {EltConfig} config
* @param {string} [config.value='']
* @return {HTMLInputElement}
*/
export function creediv (config) {
return addElt({ ...config, tag: 'div' })
}
/**
* Ajoute un <input> dans config.papa
* @param {EltConfig} config
* @param {string} [config.value='']
* @return {HTMLInputElement}
*/
export function creeinput (config) {
const input = getElt({ ...config, tag: 'input' })
if (config.value !== undefined) input.value = config.value
if (config.type) input.type = config.type
config.papa.appendChild(input)
return input
}
/**
* Ajoute un <span> dans config.papa
* @param {EltConfig} config
* @param {string} [config.value='']
* @return {HTMLSpanElement}
*/
export function creespan (config) {
const span = getElt({ ...config, tag: 'span' })
if (config.innerHTML) span.innerHTML = config.innerHTML
if (config.textContent) span.textContent = config.textContent
config.papa.appendChild(span)
return span
}
/**
* Ajoute des input radio (et leur label) dans un <span>, ajouté dans config.papa
* @param {EltConfig} config
* @param {string[]} config.value Les valeurs (utilisées aussi comme label)
* @param {string[]} config.id_radios_btn Les id des boutons radio
* @param {string} config.check La valeur du bouton radio à sélectionner
* @return {HTMLSpanElement}
*/
export function creebtnsradios (config) {
if (!Array.isArray(config.value)) throw Error('Paramètres incorrects')
const span = getElt({ ...config, tag: 'span' })
span.style.textAlign = 'center'
config.value.forEach((val, index) => {
const radiosBtn = document.createElement('input')
radiosBtn.type = 'radio'
radiosBtn.name = config.id
radiosBtn.value = val
radiosBtn.id = config.id_radios_btn[index]
if (config.check === config.value[index]) {
radiosBtn.checked = true
}
const label = document.createElement('label')
label.htmlFor = 'label' + radiosBtn.id
label.appendChild(document.createTextNode(val + ' '))
span.appendChild(radiosBtn)
span.appendChild(label)
})
config.papa.appendChild(span)
return span
}
/**
* Ajoute un tag <select>, wrappé dans un span, dans config.papa
* @param {EltConfig} config
* @param {string[]} config.value Les valeurs (utilisées aussi comme label)
* @param {string} config.prefixe Préfixe d’id sur le select (suivi de 'select' puis de nom_param)
* @param {string} config.nom_param Suffixe de l’id du select
* @return {HTMLSpanElement}
*/
export function creelisteDeroulante (config) {
const span = getElt({ ...config, tag: 'span' })
const selectElt = document.createElement('select')
selectElt.id = config.prefixe + 'select' + config.nom_param
if (Array.isArray(config.value)) {
for (const [index, val] of config.value.entries()) {
const optionElt = document.createElement('option')
if (config.selected === config.value[index]) {
optionElt.selected = true
}
optionElt.id = config.nom_param + encodeURIComponent(val)
optionElt.innerHTML = val
selectElt.appendChild(optionElt)
}
} else {
console.warn('Pas de propriété value (array) dans', config)
}
span.appendChild(selectElt)
config.papa.appendChild(span)
return span
}
/**
* Retourne le nombre X (pas forcément entier) si cssString vaut "Xpx" (undefined sinon)
* @param {string} cssString
* @return {number|undefined}
*/
export function extractNumberFromCss (cssString) {
if (/^[0-9]+px$/.test(cssString)) return Number(cssString.substr(0, cssString.length - 2))
}