/**
* @module EventView/Parts
* @local Parts
* @local FakePart
*/
export {Parts, FakePart}
/**
* @abstract
* @class
* @classdesc Représentation d'une partie de la vue de la création/édition d'un évènement. Il gère les actions visuels et comportements de cette partie.
*/
class Parts {
/**
* Constructeur de la classe. Il demande le champs qui sera gérer ainsi que son "mode de fonctionnement". (cad, si il est actionner par un clique ou un changement d'état)
* @param {external:jQuery} $field Champs qui sera gérer par cette classe.
* @param {...Parts.MODE} modes Mode de fonctionnement.
*/
constructor($field, ...modes) {
/**
* Champ qui sera gérer par cette partie. Ce champ sera utiliser pour sauvegarder les données qui lui sont liés.
* @protected
* @member
* @type {external:jQuery}
*/
this._$field = $field;
this._p_initField(modes);
}
/**
* Met à jours le champ
* @abstract
* @param {*} new_value Nouvelle valeur du champ
*/
onUpdate(new_value) {
throw "Abstract !";
}
/**
* Action qui sera appelé lorsque le champ changera de valeur.
*
* En général, appelle {@link Parts~onUpdate}
* @abstract
* @param {...any} args Le premier argument est généralement un `Event`
*/
onChange(...args) {
throw "Abstract !";
}
/**
* Action qui sera appelé lorsque l'on cliquera sur le champ
*
* En général, appelle {@link Parts~onUpdate}
* @abstract
* @param {...any} args Le premier argument est généralement un `Event`
*/
onClick(...args) {
throw "Abstract !";
}
/**
* Action qui sera appelé lorsque le champ changera de valeur alors que le focus est toujours dessus.
*
* En général, appelle {@link Parts~onUpdate}
* @abstract
* @param {...any} args Le premier argument est généralement un `Event`
*/
onInput(...args) {
throw "Abstract !";
}
/**
* Récupère le champ
* @protected
* @returns {external:jQuery}
*/
_p_get_field() {
return this._$field;
}
/**
* Initialise le champ en fonction des modes défini dans le constructeur.
* @protected
* @param {Parts.MODE[]} modes
*/
_p_initField(modes) {
let $field = this._p_get_field();
if (!!$field) {
for (const mode of modes) {
switch (mode) {
case Parts.MODE.click:
this._p_try_add_event($field, 'click', this.onClick.bind(this));
break;
case Parts.MODE.change:
this._p_try_add_event($field, 'change', this.onChange.bind(this));
break;
case Parts.MODE.input:
this._p_try_add_event($field, 'input', this.onInput.bind(this));
break;
default:
break;
}
}
}
}
/**
* @callback EventCallback
* @param {Event}
* @returns {void}
*/
/**
* Essaye d'ajouter l'évènement lié aux modes au champ
* @protected
* @param {external:jQuery} $field
* @param {string} event Nom de l'évènement que l'on souhaite ajouter {exemple : 'click'}
* @param {EventCallback} callback
* @returns {external:jQuery} Champ modifié
*/
_p_try_add_event($field, event, callback) {
if (!$._data($field[0], 'events' )?.[event]) {
$field.on(event, callback);
}
else {
$field.off(event);
$field.on(event, callback);
}
return $field;
}
}
/**
* @class
* @classdesc Représentation d'une partie de la vue d'évènement. Cette partie contient un champs visuel qui modifie le champ qui sera utiliser pour la sauvegarde de l'évènement.
* @extends Parts
*/
class FakePart extends Parts {
/**
*
* @param {external:jQuery} $field Champ qui sera modifier par le champ visuel.
* @param {externam:jQuery} $fakeField Champ visuel qui modifiera le champ de sauvegarde
* @param {...Parts.MODE} modes Mode de fonctionnement.
*/
constructor($fields, $fakeField, ...modes) {
super($fields, ...modes);
this._$fakeField = $fakeField;
this._p_initField(modes);
}
/**
* Initialise le champs visuel à partir de l'évènement
* @abstract
* @param {*} event Evènement du plugin `Calendar`
*/
init(event) {
throw "Abstract !";
}
/**
* Récupère le champ principal
* @protected
* @returns {external:jQuery}
*/
_p_get_field() {
return this._$fakeField;
}
}
/**
* Mode de fonctionnements disponible pour un champ
* @static
* @enum {Symbol}
*/
Parts.MODE = {
change:Symbol(),
click:Symbol(),
input:Symbol()
};