node-red-contrib-displayext-node
Version:
A node for software DisplayEXT
375 lines (336 loc) • 18.3 kB
HTML
<script type="text/javascript">
// convert to i18 text
function c_(x) {
return RED._("node-red-dashboard/ui_template:ui_template."+x);
}
RED.nodes.registerType('ui_templateModifyMediaDE',{
category: "Display Externe",
color: '#ffccff',
defaults: {
group: {type: 'ui_groupDE', required:true},
name: {value: ''},
order: {value: 0},
width: {value: 0, validate: function(v) {
var valid = true
if (this.templateScope !== 'global') {
var width = v||0;
var currentGroup = $('#node-input-group').val()||this.group;
var groupNode = RED.nodes.node(currentGroup);
valid = !groupNode || +width <= +groupNode.width;
$("#node-input-size").toggleClass("input-error",!valid);
}
return valid;
}},
height: {value: 0},
format: {value: `<script type="text/javascript">
(function(scope) {
let allDevices = []; // Variable pour stocker toutes les informations des devices
let originalDevice = {}; // Stocker les informations originales du device sélectionné pour comparaison
// Envoi initial du message avec payload 'none' pour cacher le popup au démarrage
scope.send({ payload: 'none' });
// Fonction d'écoute du message reçu
scope.$watch('msg', function(msg) {
if (msg && msg.payload) {
const popup = document.getElementById('popupMedia');
const overlay = document.getElementById('overlayMedia');
// Si l'action du payload est 'modify', afficher le popup
if (msg.payload.action === 'modify') {
const devices = msg.payload.media;
allDevices = devices; // On garde toutes les informations des devices dans 'allDevices'
const select = document.getElementById('device-selectMedia');
// Réinitialiser la liste déroulante et la remplir avec les appareils
select.innerHTML = '';
devices.forEach(function(device, index) {
const option = document.createElement('option');
option.value = index; // Utiliser l'index comme valeur
option.textContent = device.name;
select.appendChild(option);
});
// Afficher le popup et l'overlay
popup.style.display = 'block';
overlay.style.display = 'block';
// Par défaut, sélectionner le premier appareil et mettre à jour les champs
if (devices.length > 0) {
updateDeviceInfo(devices[0]); // Met à jour les champs avec les infos du premier device
originalDevice = { ...devices[0] }; // Sauvegarder les informations originales du device
}
}
// Si l'action est 'none', masquer le popup
else if (msg.payload === 'none') {
popup.style.display = 'none';
overlay.style.display = 'none';
}
}
});
// Fonction pour fermer le popup
function closePopup() {
const popup = document.getElementById('popupMedia');
const overlay = document.getElementById('overlayMedia');
popup.style.display = 'none';
overlay.style.display = 'none';
}
// Fonction pour valider la sélection et fermer le popup
function validateSelection() {
const select = document.getElementById('device-selectMedia');
const selectedIndex = select.value;
if (selectedIndex !== '') {
const selectedDevice = allDevices[selectedIndex];
scope.send({ payload: { action: 'deviceSelected', device: selectedDevice } });
closePopup();
} else {
alert('Please select a device.');
}
}
// Fonction pour mettre à jour les champs avec les informations du device sélectionné
function updateDeviceInfo(device) {
document.getElementById('nameFieldMedia').value = device.name || '';
document.getElementById('ipFieldMedia').value = device.ip || '';
document.getElementById('portFieldMedia').value = device.port || '';
}
// Fonction pour supprimer un device
function deleteDevice() {
const select = document.getElementById('device-selectMedia');
const selectedIndex = select.value;
if (selectedIndex !== '') {
const selectedDevice = allDevices[selectedIndex];
// Envoie un message pour supprimer le device
scope.send({ payload: { action: 'deleteMedia', mediaName: selectedDevice.name } });
closePopup();
} else {
alert('Please select a device to delete.');
}
}
// Fonction pour vérifier si des modifications ont été apportées et envoyer un message avec les données modifiées
function submitChanges() {
const name = document.getElementById('nameFieldMedia').value;
// const ip = document.getElementById('ipFieldMedia').value;
// const port = document.getElementById('portFieldMedia').value;
const select = document.getElementById('device-selectMedia');
const selectedIndex = select.value;
const selectedDevice = allDevices[selectedIndex];
// Vérifier si des modifications ont été effectuées
if (name !== selectedDevice.name) {
const updatedDevice = {
oldName: selectedDevice.name, // Ajouter l'ancien name dans le message
name: name,
// ip: ip,
// port: port,
};
// Envoyer les informations modifiées si nécessaire
scope.send({ payload: { action: 'updateMedia', media: updatedDevice } });
}
closePopup();
}
// Ajout des écouteurs d'événements pour la mise à jour et la suppression du device
document.getElementById('cancelBtnMedia').addEventListener('click', closePopup);
document.getElementById('submitBtnMedia').addEventListener('click', submitChanges);
document.getElementById('deleteBtnMedia').addEventListener('click', deleteDevice);
// Ajout d'un écouteur d'événements pour la sélection d'un device dans la liste
document.getElementById('device-selectMedia').addEventListener('change', function() {
const select = document.getElementById('device-selectMedia');
const selectedIndex = select.value;
// Si un nouveau device est sélectionné, on met à jour l'état et les champs
if (selectedIndex !== '') {
const selectedDevice = allDevices[selectedIndex];
updateDeviceInfo(selectedDevice); // Met à jour les champs avec les infos du nouveau device
originalDevice = { ...selectedDevice }; // Sauvegarder les informations originales du device
}
});
})(scope);
`+`<`+`/script>
<!-- Overlay pour la transparence derrière le popup -->
<div id="overlayMedia"
style="display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);backdrop-filter:blur(5px);z-index:9998;">
</div>
<!-- Popup avec la liste déroulante pour sélectionner un appareil -->
<div id="popupMedia"
style="display:none;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:rgb(72 72 72);color:#fff;padding:20px;border-radius:10px;box-shadow:0 4px 8px rgba(0,0,0,0.3);text-align:center;width:300px;z-index:9999;">
<h3
style="margin-bottom:15px;border-radius:5px;background-color:#3a3a3a!important;color:aliceblue!important;padding:4px;">
Modify Device</h3>
<label for="device-selectMedia" style="display:block;margin-bottom:5px;text-align:left;">Media:</label>
<select id="device-selectMedia" style="width:100%;padding:8px;margin-bottom:10px;border:1px solid #a600ff;border-radius:5px;background:#444;color:#fff;">
<option value="">-- Select a media --</option>
</select>
<label for="nameFieldMedia" style="display:block;margin-top:10px;text-align:left;">Name:</label>
<input type="text" id="nameFieldMedia" style="width:-webkit-fill-available;padding:8px;margin-bottom:10px;border:1px solid #00bfb4;border-radius:5px;background:#444;color:#fff;">
<!-- <label for="ipFieldMedia" style="display:block;margin-top:10px;text-align:left;">IP:</label>
<input type="text" id="ipFieldMedia" style="width:-webkit-fill-available;padding:8px;margin-bottom:10px;border:1px solid #555;border-radius:5px;background:#444;color:#fff;">
<label for="portFieldMedia" style="display:block;margin-top:10px;text-align:left;">Port:</label>
<input type="number" id="portFieldMedia" style="width:-webkit-fill-available;padding:8px;margin-bottom:10px;border:1px solid #555;border-radius:5px;background:#444;color:#fff;"> -->
<div style="display:flex;gap:10px;justify-content:center;margin-top:15px;">
<button id="cancelBtnMedia" style="background-color:#f44336;color:white;padding:10px 20px;border:none;border-radius:5px;cursor:pointer;">Cancel</button>
<button id="submitBtnMedia" style="background-color:#4CAF50;color:white;padding:10px 20px;border:none;border-radius:5px;cursor:pointer;">Submit</button>
<button id="deleteBtnMedia" style="background-color:#f44336;color:white;padding:10px 20px;border:none;border-radius:5px;cursor:pointer;">Delete</button>
</div>
</div>`},
storeOutMessages: {value: true},
fwdInMessages: {value: false},
resendOnRefresh: {value: true},
templateScope: {value: 'local'},
className: {value: ''}
},
inputs:1,
outputs:1,
icon: "icon.png",
paletteLabel: 'Popup Modif Media',
label: function() { return this.name || 'Popup Modif Media'; },
labelStyle: function() { return this.name?"node_label_italic":""; },
oneditprepare: function() {
if (RED.editor.hasOwnProperty("editText") && typeof RED.editor.editText === "function") {
$("#node-template-expand-editor").show();
}
else {
$("#node-template-expand-editor").hide();
}
var that = this;
$("#node-input-size").elementSizer({
width: "#node-input-width",
height: "#node-input-height",
group: "#node-input-group"
});
if (typeof this.storeOutMessages === 'undefined') {
this.storeOutMessages = true;
$('#node-input-storeOutMessages').prop('checked', true);
}
if (typeof this.fwdInMessages === 'undefined') {
this.fwdInMessages = true;
$('#node-input-fwdInMessages').prop('checked', true);
}
if (typeof this.templateScope === 'undefined') {
this.templateScope = 'local';
$('#node-input-templateScope').val(this.templateScope);
}
$('#node-input-templateScope').on('change', function() {
if ($('#node-input-templateScope').val() === 'global') {
$('#template-row-group, #template-row-size, #template-pass-store, #template-row-class').hide();
that._def.defaults.group.required = false;
}
else {
$('#template-row-group, #template-row-size, #template-pass-store, #template-row-class').show();
that._def.defaults.group.required = true;
}
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
var height = $("#dialog-form").height();
for (var i=0; i<rows.size(); i++) {
height = height - $(rows[i]).outerHeight(true);
}
if ($('#node-input-templateScope').val() === "global") { height += 240; }
var editorRow = $("#dialog-form>div.node-text-editor-row");
height -= (parseInt(editorRow.css("marginTop")) + parseInt(editorRow.css("marginBottom")));
$(".node-text-editor").css("height",height+"px");
if (this.editor) { this.editor.resize(); }
})
this.editor = RED.editor.createEditor({
id: 'node-input-format-editor',
mode: 'ace/mode/html',
value: $("#node-input-format").val()
});
RED.library.create({
url:"uitemplates", // where to get the data from
type:"ui_template", // the type of object the library is for
editor:this.editor, // the field name the main text body goes to
mode:"ace/mode/html",
fields:['name']
});
this.editor.focus();
RED.popover.tooltip($("#node-template-expand-editor"),c_("label.expand"));
$("#node-template-expand-editor").on("click", function(e) {
e.preventDefault();
var value = that.editor.getValue();
RED.editor.editText({
mode: 'html',
value: value,
width: "Infinity",
cursor: that.editor.getCursorPosition(),
complete: function(v,cursor) {
that.editor.setValue(v, -1);
that.editor.gotoLine(cursor.row+1,cursor.column,false);
setTimeout(function() { that.editor.focus(); },300);
}
})
})
},
oneditsave: function() {
var annot = this.editor.getSession().getAnnotations();
this.noerr = 0;
$("#node-input-noerr").val(0);
for (var k=0; k < annot.length; k++) {
if (annot[k].type === "error") {
$("#node-input-noerr").val(annot.length);
this.noerr = annot.length;
}
}
$("#node-input-format").val(this.editor.getValue());
this.editor.destroy();
delete this.editor;
},
oneditcancel: function() {
this.editor.destroy();
delete this.editor;
},
oneditresize: function(size) {
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
var height = $("#dialog-form").height();
for (var i=0; i<rows.size(); i++) {
height = height - $(rows[i]).outerHeight(true);
}
if ($('#node-input-templateScope').val() === "global") { height += 232; }
var editorRow = $("#dialog-form>div.node-text-editor-row");
height -= (parseInt(editorRow.css("marginTop")) + parseInt(editorRow.css("marginBottom")));
$(".node-text-editor").css("height",height+"px");
this.editor.resize();
}
});
</script>
<script type="text/html" data-template-name="ui_templateModifyMediaDE">
<!-- <div class="form-row">
<label for="node-input-format"><span data-i18n="ui_templateModifyMediaDE.label.type"></span></label>
<select style="width:76%" id="node-input-templateScope">
<option value="local" data-i18n="ui_templateModifyMediaDE.label.local"></option>
<option value="global" data-i18n="ui_templateModifyMediaDE.label.global"></option>
</select>
</div> -->
<div class="form-row" id="template-row-group">
<label for="node-input-group"><i class="fa fa-table"></i> <span data-i18n="ui_templateModifyMediaDE.label.group"></span></label>
<input type="text" id="node-input-group">
</div>
<div class="form-row" id="template-row-size">
<label><i class="fa fa-object-group"></i> <span data-i18n="ui_templateModifyMediaDE.label.size"></span></label>
<input type="hidden" id="node-input-width">
<input type="hidden" id="node-input-height">
<button class="editor-button" id="node-input-size"></button>
</div>
<!-- <div class="form-row" id="template-row-class">
<label for="node-input-className"><i class="fa fa-code"></i> <span data-i18n="ui_templateModifyMediaDE.label.className"></label>
<input type="text" id="node-input-className" data-i18n="[placeholder]ui_templateModifyMediaDE.label.classNamePlaceholder"/>
</div> -->
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<div style="display:inline-block; width:calc(100% - 105px)">
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
</div>
</div>
<div class="form-row" style="display:none;margin-bottom:0px; ">
<label for="node-input-format"><i class="fa fa-copy"></i> <span data-i18n="ui_templateModifyMediaDE.label.template"></span></label>
<input type="hidden" id="node-input-format">
<button id="node-template-expand-editor" class="red-ui-button red-ui-button-small" style="float:right"><i class="fa fa-expand"></i></button>
</div>
<!-- <div class="form-row node-text-editor-row">
<div style="height:250px; min-height:100px" class="node-text-editor" id="node-input-format-editor" ></div>
</div> -->
<!-- <div id="template-pass-store">
<div class="form-row" style="margin-bottom:0px;">
<input type="checkbox" id="node-input-fwdInMessages" style="display:inline-block; margin-left:8px; width:auto; vertical-align:top;">
<label for="node-input-fwdInMessages" style="width:70%;"> <span data-i18n="ui_templateModifyMediaDE.label.pass-through"></span></label>
</div>
<div class="form-row" style="margin-bottom:0px;">
<input type="checkbox" id="node-input-storeOutMessages" style="display:inline-block; margin-left:8px; width:auto; vertical-align:top;">
<label for="node-input-storeOutMessages" style="width:70%;"> <span data-i18n="ui_templateModifyMediaDE.label.store-state"></span></label>
</div>
<div class="form-row" style="margin-bottom:0px;">
<input type="checkbox" id="node-input-resendOnRefresh" style="display:inline-block; margin-left:8px; width:auto; vertical-align:top;">
<label for="node-input-resendOnRefresh" style="width:70%;"> <span data-i18n="ui_templateModifyMediaDE.label.resend"></span></label>
</div>
</div> -->
</script>