How to show modal dialog in template node

I think you'll need to change your JS variables names as well, ex:

var modal2 = document.getElementById('secondModal');

// Get the button that opens the modal
var btn2 = document.getElementById("second");

There is a solution for multiple modal in one tab.

<style>
body {font-family: Arial, Helvetica, sans-serif;}

/* The Modal (background) */
.modal {
    display: none; /* Hidden by default */
    position: fixed; /* Stay in place */
    opacity:0.99;
    z-index: 100; /* Sit on top */
    padding-top: 100px; /* Location of the box */
    left: 0;
    top: 0;
    width: 100%; /* Full width */
    height: 100%; /* Full height */
    overflow: auto; /* Enable scroll if needed */
    background-color: rgb(0,0,0); /* Fallback color */
    background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}

/* Modal Content */
.modal-content {
    position: relative;
    background-color: #fefefe;
    margin: auto;
    padding: 0;
    border: 1px solid #888;
    width: 50%;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
    -webkit-animation-name: animatetop;
    -webkit-animation-duration: 0.4s;
    animation-name: animatetop;
    animation-duration: 0.4s
}

/* Add Animation */
@-webkit-keyframes animatetop {
    from {top:-300px; opacity:0} 
    to {top:0; opacity:1}
}

@keyframes animatetop {
    from {top:-300px; opacity:0}
    to {top:0; opacity:1}
}

/* The Close Button */
.close {
    color: white;
    float: right;
    font-size: 28px;
    font-weight: bold;
}

.close:hover,
.close:focus {
    color: #000;
    text-decoration: none;
    cursor: pointer;
}

.modal-header {
    padding: 2px 16px;
    background-color: #5cb85c;
    color: white;
}

.modal-body {padding: 2px 16px;}

.modal-footer {
    padding: 2px 16px;
    background-color: #5cb85c;
    color: white;
}
</style>

<!-- Trigger/Open The Modal -->
<button class="modal-button" href="{{'#myModal_'+$id}}">Bedienung</button>

<!-- The Modal -->
<div id="{{'myModal_'+$id}}" class="modal">

  <!-- Modal content -->
  <div class="modal-content">
    <div class="modal-header">
      <span class="close">&times;</span>
      <h2>Modal Header</h2>
    </div>
    <div class="modal-body">
      <p>Some text in the Modal Body</p>
      <div>
        Qty of silly hats
  <input type="number" ng-model="msg.payload" name="quantity" min="0" max="1000">
  <md-button ng-click="send(msg)">Click to send to Node-Red</md-button>
</div>
    </div>
    <div class="modal-footer">
      <h3>Modal Footer</h3>
    </div>
  </div>

</div>

<script>
// Get the button that opens the modal
var btn = document.querySelectorAll("button.modal-button");

// All page modals
var modals = document.querySelectorAll('.modal');

// Get the <span> element that closes the modal
var spans = document.getElementsByClassName("close");

// When the user clicks the button, open the modal
for (var i = 0; i < btn.length; i++) {
 btn[i].onclick = function(e) {
    e.preventDefault();
    modal = document.querySelector(e.target.getAttribute("href"));
    modal.style.display = "block";
 }
}

// When the user clicks on <span> (x), close the modal
for (var i = 0; i < spans.length; i++) {
 spans[i].onclick = function() {
    for (var index in modals) {
      if (typeof modals[index].style !== 'undefined') modals[index].style.display = "none";    
    }
 }
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
    if (event.target.classList.contains('modal')) {
     for (var index in modals) {
      if (typeof modals[index].style !== 'undefined') modals[index].style.display = "none";    
     }
    }
}
</script>
2 Likes

Thought this would be useful to anyone who is trying to use mdDialog service.
This past 2 days I was trying to get this to work, and I was able to get the existing mdDialog service by using injector.
Below is a sample code just to make it work (my apology for the alignment). You will still need to look at angularjs doc for more info on angularjs injector API params.

(function(scope){
var testShowAlert = function ($mdDialog) {
var alert = $mdDialog.alert({
title: 'Attention',
textContent: 'This is an example of how simple dialogs can be!',
ok: 'Close'
});

  $mdDialog
    .show( alert )
    .finally(function() {
      alert = undefined;
    });

}

scope.showAlert = function() {
       var injector = angular.element("#nr-dashboard").injector();
       injector.invoke(testShowAlert,null,null);
};

})(scope);

2 Likes

Hello,

Thank you for your sample code. How are you calling the showAlert function? I don't understand how to place this in a ui_template node for example. Can you share a flow export?

Thank you

Hi Nate,
Here it is in ui_template node:

<script>
(function(scope){
var testShowAlert = function ($mdDialog) {
var alert = $mdDialog.alert({
title: 'Attention',
textContent: 'This is an example of how simple dialogs can be!',
ok: 'Close'
});

  $mdDialog
    .show( alert )
    .finally(function() {
      alert = undefined;
    });

}

scope.showAlert = function() {
       var injector = angular.element("#nr-dashboard").injector();
       injector.invoke(testShowAlert,null,null);
};

})(scope);
</script>
<button ng-click="showAlert()">Test Alert</button>

Forewarned, this relies the id to always be "nr-dashboard."
And also get yourself familiar with angularjs. Below is the reference to ng-click:
https://docs.angularjs.org/api/ng/directive/ngClick

1 Like

Hi,

I have managed to wrangle this code to my needs and its working well BUT !!

I'm opening it using a msg payload rather than a button. This then displays on the correct browser, I also added a couple of buttons to display next images etc.

When I use one of these buttons the modal then popups up on ALL browser sessions showing the image before the one on the "correct" browser (socket.id is included in button msg).
I need it to only open on the browser that is clicked on. Can anyone offer some help please ?

<style>
    body {
        font-family: Arial, Helvetica, sans-serif;
    }

    /* The Modal (background) */
    .modal {
        display: none;
        /* Hidden by default */
        position: fixed;
        /* Stay in place */
        opacity: 0.99;
        z-index: 100;
        /* Sit on top */
        padding-top: 100px;
        /* Location of the box */
        left: 0;
        top: 0;
        width: 100%;
        /* Full width */
        height: 100%;
        /* Full height */
        overflow: auto;
        /* Enable scroll if needed */

    }

    /* Modal Content */
    .modal-content {
        position: relative;
        margin: auto;
        padding: 0;
        border: 1px solid #888;
        background: var(--nr-dashboard-groupBackgroundColor);
        color: var(--nr-dashboard-widgetTextColor);
        width: 934px;
        box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
        -webkit-animation-name: animatetop;
        -webkit-animation-duration: 0.9s;
        animation-name: animatetop;
        animation-duration: 0.9s
    }

    /* Add Animation */
    @-webkit-keyframes animatetop {
        from {
            top: -300px;
            opacity: 0
        }

        to {
            top: 0;
            opacity: 1
        }
    }

    @keyframes animatetop {
        from {
            top: -300px;
            opacity: 0
        }

        to {
            top: 0;
            opacity: 1
        }
    }

    /* The Close Button */
    .close {
        color: white;
        float: right;
        font-size: 28px;
        font-weight: bold;
    }

    .close:hover,
    .close:focus {
        color: #000;
        text-decoration: none;
        cursor: pointer;
    }

    .modal-header {
        padding: 2px 16px;

    }

    .modal-body {
        padding: 2px 16px;
    }

    .modal-footer {
        padding: 2px 16px;

    }
</style>

<!-- The Modal -->
<div id="myModal" class="modal">

    <!-- Modal content -->
    <div class="modal-content">
        <div class="modal-header">
            <span class="close">&times;</span>
            <h2>Preview</h2>
        </div>
        <div class="modal-body">
            <img src="" height="576" width="900" id="image">
            <div>
                <md-button id="mBtn2" ng-click="msg.action = 'prev';send(msg)">prev</md-button>
                <md-button id="mBtn1" ng-click="msg.action = 'next';send(msg)">next</md-button>
                <button class="md-button md-ink-ripple" id="mBtn3">close</button>
            </div>
        </div>
        <div class="modal-footer">
            <h3>Record {{msg.index}}</h3>
        </div>
    </div>

</div>


<script>
    // Get the modal
var modal = document.getElementById('myModal');

var closebtn = document.getElementById('mBtn3');

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

// When the user clicks on <span> (x), close the modal
span.onclick = function() {
    modal.style.display = "none";
}
closebtn.onclick = function() {
    modal.style.display = "none";
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
    if (event.target == modal) {
        modal.style.display = "none";
    }
}

</script>
<script>
    (function(scope) {
        scope.$watch('msg', function (data) {
            if(data !== null) {
                if (data.hasOwnProperty('display')) {
                    if (data.display == true) { modal.style.display = "block" }
                    if (data.display == false) { modal.style.display = "none" }
                }
                if (data.hasOwnProperty('image')) {
                    { image.src = data.image }
                }
            }

        });
    })(scope);


</script>

@hugobox Not sure if you are using the modal code you posted, could you check the above to see if you can see why its opening on all browsers when next prev buttons are used please ?
I include the session.id in the message returned to the modal script, but maybe I did something silly ?

Hi @smcgann99 !
Try removing the ui-template's checkbox "Add output messages to stored state." I think this option overwrites the state on all sessions.

1 Like

Many thanks that did the trick :wink:

TBH I don't really know what that option is for do you ?

If I'm not mistaken, it takes the msg output of the ui-template and sends it via websockets to all browser sessions.

1 Like

Thank you for your good code

1 Like