• Recent
    • Tags
    • Popular
    • Register
    • Login

    Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

    Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website Mango 5 Documentation Website

    Pop up window (face plate)

    Wishlist
    6
    20
    4.9k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • I
      iperry
      last edited by

      Hi @MattFox

      Are you still able to post a sample of a modal popup? I was able to get the user module example created and working but I have yet been able to find an example of a modal that seems to fit within the framework.

      The intention of the modal is to allow users to add information about a sensor, such as GPS coordinates, add alarm setpoints, calibration values, etc. This data would then be saved to either a (virtual) data point or the JSON store.

      Thanks
      Ian

      1 Reply Last reply Reply Quote 0
      • MattFoxM
        MattFox
        last edited by

        Sure happy to. I won't be near a computer today due to having to work off site. I will however quite happily smack out tomorrow for you both. If that's ok.
        Thanks for giving me your requirements Ian, I'll whack it out fairly quickly.

        Fox

        Do not follow where the path may lead; go instead where there is no path.
        And leave a trail - Muriel Strode

        1 Reply Last reply Reply Quote 0
        • I
          iperry
          last edited by

          Thanks, that would be great. Don't go to too much trouble on it. :)

          1 Reply Last reply Reply Quote 0
          • MattFoxM
            MattFox
            last edited by MattFox

            OK!
            As a starting point to work from. I'll work with you so you learn how it all works as you go...
            (All code is placed in the /opt/mango/overrides/web... directories)
            /modules/mangoUI/web/dev/components/settingsModal.js

            define(['angular', 'require'], function(angular, require) {
            'use strict';
            
            /* Date: 1/9/18
            	   Author: Matt "Fox" Fox
            	   Desc: component written to launch a modal dialog with either a built in template or just spit out a list of points to save one by one.
            	*/
            	settingsModalController.$inject = ['$mdDialog','maJsonStore'];
            		function settingsModalController ($mdDialog,maJsonStore)
            		{
            			var ctrl = this;
            			ctrl.mdDialog = $mdDialog;
            			ctrl.parsedOptions=[];
            			
            			ctrl.values={};
            			
            			this.$onInit = function()
            			{
            				if(this.points && !angular.isArray(this.points))
            				{
            					console.log('Error: points field not an array of point objects');
            				}
            				if(this.pointOptions && !angular.isArray(this.pointOptions) )
            				{
            					console.log('Error: points options field not an array');
            				}
            				ctrl.clickOffClose = ctrl.clickOffClose===true?true:false;
            				
            				
            				
            				
            				
            			};
            			
            			this.$onChanges = function(e)
            			{
            				console.log(e);
            				checkPoints();
            			}
            			
            			function checkPoints()
            			{
            				ctrl.parsedOptions=[];
            				if(ctrl.points && angular.isArray(ctrl.points))
            				{
            					if(ctrl.pointOptions && angular.isArray(ctrl.pointOptions) )
            					{
            						var ptName,ptDesc;
            						for(var i=0; i<ctrl.points.length; i++)
            						{
            							ptName=ctrl.points[ i ].name;
            							ptDesc='';
            							if(ctrl.pointOptions[ i ] && ctrl.pointOptions[ i ].hasOwnProperty('name') )
            							{
            								ptName = ctrl.pointOptions[ i ].name;
            							}
            							if(ctrl.pointOptions[ i ] && ctrl.pointOptions[ i ].hasOwnProperty('desc') )
            							{
            								ptDesc = ctrl.pointOptions[ i ].desc;
            							}
            							ctrl.parsedOptions.push( {name:ptName,desc:ptDesc} );
            						}
            					}
            					else
            					{
            						for(var i=0; i<ctrl.points.length; i++)
            						{
            							ptName=ctrl.points[ i ].name;
            							ptDesc='';
            						
            							ctrl.parsedOptions.push( {name:ptName,desc:ptDesc} );
            						}
            					}
            				}
            				else if(ctrl.pointOptions && angular.isArray(ctrl.pointOptions) && !ctrl.points )
            				{	
            					var ptId, ptName, ptDesc;
            					for(var i=0; i<ctrl.pointOptions.length; i++)
            					{
            						if(ctrl.pointOptions[ i ] && !ctrl.pointOptions[ i ].hasOwnProperty('name') )
            						{
            							// ctrl.pointOptions=[];
            							ctrl.parsedOptions=[];
            							return;
            						}
            						ptId=i;
            						ptDesc='';
            						ptName=ctrl.pointOptions[ i ].name;
            						if(ctrl.pointOptions[ i ] && ctrl.pointOptions[ i ].hasOwnProperty('id') )
            						{
            							ptId = ctrl.pointOptions[ i ].id;
            						}
            						if(ctrl.pointOptions[ i ] && ctrl.pointOptions[ i ].hasOwnProperty('desc') )
            						{
            							ptDesc = ctrl.pointOptions[ i ].desc;
            						}						
            						ctrl.parsedOptions.push( {id:ptId,name:ptName,desc:ptDesc} );
            					}
            				}
            			}
            			
            			/* DIALOG CODE */
            			ctrl.showDialogue = function(ev) {
            			   // ctrl.updateModals();
            			   if( ctrl.altTemplateUrl!==undefined  )
            			   {
            				   try
            				   {
            					   
            					ctrl.mdDialog.show({
            					  templateUrl:ctrl.altTemplateUrl, 
            					  parent: angular.element(document.body),
            					  targetEvent: ev,
            					  clickOutsideToClose: ctrl.clickOffClose
            					}).then(
            						function()
            						{
            							console.log('function if closed/hidden manually'); 
            						},
            						function()
            						{
            							console.log('function to fire if closed from clicking outside/cancelled');
            						}
            					);
            				   }catch(e){console.warn(e);}
            			   }
            			   else
            			   {
            				   try{
            					   
            					ctrl.mdDialog.show({
            					  contentElement: '#settingsModal',
            					  parent: angular.element(document.body),
            					  targetEvent: ev,
            					  clickOutsideToClose: ctrl.clickOffClose
            					}).then(
            						function()
            						{
            							console.log('function if closed manually'); 
            						},
            						function()
            						{
            							console.log('function to fire if closed from clicking outside/cancelled');
            						}
            					);
            				   }catch(e){console.warn(e);}
            				}
            			};
            			
            			ctrl.hideDialogue = function() {
            				ctrl.mdDialog.hide();
            			};
            
            			ctrl.cancel = function() {	  
            				ctrl.mdDialog.cancel();
            			};
            			/* DIALOG CODE END*/
            			
            			/* JSON Store Stuff: */
            			ctrl.saveToStore = function(data=null)
            			{
            				
            				var item = maJsonStore.newItem( ctrl.jsonStore.toLowerCase() );
            				item.jsonData = data===null ? ctrl.values : data;
            				item.readPermission= "user";
            				item.editPermission= "user"; //can change this at your leisure or we can break it out into a setting...
            				
            				var r = item.$save();
            				
            				if(r.status)
            				{ 
            				}
            				else
            				{ 
            				}
            			};
            			
            			ctrl.loadFromStore = function()
            			{
            				maJsonStore.get({xid: ctrl.jsonStore.toLowerCase() }).$promise.then(function(item) {
            				ctrl.values = item.jsonData;
            			});
            			/* JSON Store Stuff END: */
            			};
            			
            			/* Virtual Point Save stuff */
            			ctrl.saveToPoint = function()
            			{
            				if(ctrl.savePoint===undefined)
            				{
            					alert('Point to save to not set as attribute!');
            					return;
            				}
            				ctrl.savePoint.setValue( JSON.stringify(ctrl.values) );
            			};	
            			
            			/* Virtual Point Save stuff END */
            	}
            		
            		
            		
            	
            	var settingsModal={
            		bindings:{
            			jsonStore: '<?', 		//Store name to save settings to
            			savePoint: '<?', 		//alternatively, save my JSON to a virtual pt, MUST BE TYPE DATAPOINT...
            			altTemplateUrl:'=?', 	//If we want to use the popup to show something else: use this template...
            			modalTitle:'=?', 		//seemed like a good idea at the time... will only work if altTemplateUrl is empty
            			clickOffClose:'=?', 	//set to true to click outside modal to shut it
            			pointOptions:'<?', 	//Alternate names for points,  (object array) [{id:'',name:'',desc:''}], id used for key name if using json/virtual point save
            			points: '<?',			 //Array of points to set individually
            		},
            		controller: settingsModalController,
            		templateUrl:'/modules/mangoUI/web/dev/views/modalDemo.html'
            	};
            	
            	return settingsModal;
            });
            

            and the template markup to add:
            /modules/mangoUI/web/dev/views/modalDemo.html

             <ma-button  hue="hue-2" palette="primary" label="Open Dialogue" ng-click="$ctrl.showDialogue()" raised="true"></ma-button>
             <div ng-if="!$ctrl.altTemplateUrl" style="visibility: hidden">
                <div class="md-dialog-container" id="settingsModal">
                  <md-dialog layout-padding>
            			<md-dialog-actions><md-button ng-if="!$ctrl.clickOffClose" ng-click="$ctrl.cancel()" class="md-primary">x</md-button></md-dialog-actions>
             <div ng-if="!$ctrl.points && !$ctrl.parsedOptions">
            		Custom markup needed!
            		</div>
            		 
                   <h1 ng-if="$ctrl.modalTitle!==undefined">{{$ctrl.modalTitle}}</h1> <small ng-if="$ctrl.clickOffClose">Click outside dialogue to close</small>
            		
            		<div ng-if="$ctrl.points">
            		<md-input-container ng-repeat="(index,point) in $ctrl.points" style="display:block;width:100%;">
            	   {{$ctrl.parsedOptions[index].name}}
            			<br/>	
            	   {{$ctrl.parsedOptions[index].desc}}
            			<br/>	
            			
            		<span style="display:inline-block;">Current Value: <ma-point-value style="display:inline-block;" point="point" ></ma-point-value></span>
            		 <ma-set-point-value  point="point" show-button="true"></ma-set-point-value> 
            		</md-input-container>
            		</div>
            		<div ng-if="!$ctrl.points && $ctrl.parsedOptions.length>0">
            			<md-input-container ng-repeat="input in $ctrl.parsedOptions">
            			{{input.name}}<br/>{{input.desc}}
            			<input ng-model="$ctrl.values[ input.id ]"/>
            			</md-input-container>
            		</div>
            		
                  </md-dialog>
                </div>
              </div>
            

            More than happy to help you work through this (it will be a bit of a crash course)
            I've not added the buttons on the template for saving using a virtual point or JSON store, but that can be added quite easily.
            Basically you can generate a popup which will populate with inputs that can be named, given an ID and a description if necessary. This can also be used to override point names to more 'user friendly' equivalents for your users if they're filling out items in the dialogue box.

            inside the userModule.js directory (assuming that's the name of the file you've followed from Jared's tutorial) you'll want this structure:

            /userModule.js
            /components/settingsModal.js
            /views/modalDemo.html

            and inside userModule.js you'll want this:

            define(['angular', 'require','./components/settingsModal.js'], function(angular, require,settingsModal) {
                'use strict';
             var userModule = angular.module('userModule', ['maUiApp']);
            try {	
            	userModule.component('settingsModal', settingsModal);
            }
            catch(e){console.log(e);}	
                return userModule;
            });
            

            Markup in the dashboard page builder will be:

            <settings-modal point-options="[{id:'test',name:'input 1',desc:'input test 1'},{id:'test2',name:'input 2',desc:'input test 2'}]" points="vp" click-off-close="true"></settings-modal>
            

            See if you can get the popup showing for you first. I'm using 3.4.1 so I'm not completely sure if this will be affected in your version of mangoUI...

            Fox

            EDIT: sorry I'll be sure to add some more code comments later...
            New Edit: added data to save to store as an optional argument

            Do not follow where the path may lead; go instead where there is no path.
            And leave a trail - Muriel Strode

            1 Reply Last reply Reply Quote 2
            • CraigWebC
              CraigWeb
              last edited by

              For anyone following this thread:
              found a small typo on the useModule.js code. The try block needs to be closed with a }.

              @MattFox Thank you very much for doing this. I've been wanting to dive into modules for sometime now but have never been able to find the time. This will really help with the learning curve.

              There is just one thing that has got me here. When I try add a 2nd userModule my previous one disappears. Could someone help me with how to do this correctly, it will be very much appreciated.

              1 Reply Last reply Reply Quote 0
              • MattFoxM
                MattFox
                last edited by MattFox

                Thanks regarding the typo, I'll take a look and will correct it.
                As for your user module. You only have one. You append all of your components and controllers to it.
                I use a try catch to see where it fails. if you wrap them around each module then you can successfully determine how things are failing without breaking the entire module and losing all of your components/controllers...
                Happy to take a look for you. Otherwise feel free to private message me, same goes for Ian and Joey.

                EDIT:have corrected by adding missing brace

                Do not follow where the path may lead; go instead where there is no path.
                And leave a trail - Muriel Strode

                1 Reply Last reply Reply Quote 0
                • CraigWebC
                  CraigWeb
                  last edited by

                  @MattFox Thanks for that tip, I edit the userModule.js like this to add a second module. don't get any console errors.

                  define(['angular', 'require','./components/settingsModal.js'], function(angular, require,settingsModal) {
                      'use strict';
                   var userModule = angular.module('userModule', ['maUiApp']);
                  try {	
                  	userModule.component('settingsModal', settingsModal);
                      }
                  catch(e){console.log(e);}	
                  
                  try{userModule.component('myComponent', {
                      bindings: {
                          name: '@?'
                      },
                      template: '<span>Hello {{$ctrl.name}}</span>'
                  });
                  }
                  catch(e){console.log(e);}
                  
                      return userModule;
                  });
                  
                  1 Reply Last reply Reply Quote 0
                  • MattFoxM
                    MattFox
                    last edited by

                    Well if there is nothing being printed in the console, that's a sign of something working....
                    Do note that console.log() outputs as an informative text. If you're using chrome, ensure under the console for default levels that it's ticked:
                    0_1536033304366_69b04a4b-7b42-4aae-95a8-6b49c32ada99-image.png

                    Secondly, check on the page you have myComponent on and check the console there to ensure there is not some silly form of a clash etc...

                    Fox

                    Do not follow where the path may lead; go instead where there is no path.
                    And leave a trail - Muriel Strode

                    1 Reply Last reply Reply Quote 0
                    • I
                      iperry
                      last edited by

                      Thanks Matt, I was able to get your example working. Now to play around with retrieving and saving data to a data point or JSON store.

                      One thing that confused me was the folder structure that was required. I followed the (Jared's) tutorial that you linked which created the userModule.js in /rest/v2/file-stores/public/userModule.js. You mentioned that within this directory I need to create:
                      /components/settingsModal.js
                      /views/modalDemo.html

                      Also, you mentioned creating these directories and files under: /mango/overrides/web/modules/mangoUI/web/dev/

                      It seemed odd that the files would (appear to) be duplicated in these 2 locations.

                      What I found to work was that the settingsModal.js was located in:
                      /rest/v2/file-stores/public/components/settingsModal.js (based on the path defined in the userModal.js)
                      and the modalDemo.html was located in:
                      /mango/overrides/web/modules/mangoUI/web/dev/views/modalDemo.html (based on the path defined in settingsModal.js)

                      Is this correct? It would seem to be bit of a maintenance pain to have the files located in different contexts.

                      This example was great. Thanks again

                      Ian

                      1 Reply Last reply Reply Quote 0
                      • MattFoxM
                        MattFox
                        last edited by MattFox

                        So sorry Ian, didn't mean to perplex you.
                        I store all of my files in /opt/mango/overrides/web/modules/mangoUI/web/dev directories.
                        0_1536107492653_afcae342-46ab-4138-9e67-6038b10693e4-image.png
                        This way I don't need to concern myself with changes or being overwritten with mango updates.

                        So by this I mean userModule.js is
                        /opt/mango/overrides/web/modules/mangoUI/web/dev/userModule.js

                        the modalDemo.html:
                        /opt/mango/overrides/web/modules/mangoUI/web/dev/views/modalDemo.html

                        and the settingsModal.js file is in
                        /opt/mango/overrides/web/modules/mangoUI/web/dev/components/settingsModal.js

                        The reason I do this is to better segment my code. You can put it all in one directory if you'd rather, but as I have done a lot of MVC programming in my PHP days I'm used to separating my model, controller and views for consistency.

                        @iperry said in Pop up window (face plate):

                        Now to play around with retrieving and saving data to a data point or JSON store.

                        If you look under the settingsModal.js I've done some code for you to do that.
                        Just add a button to the view and call the method with $ctrl.saveToStore( ) or for a virtual point,
                        make sure you simply set your virtual point in the savePoint attribute and call the. $ctrl.saveToPoint() method.

                        Hmm, should remove that (data) argument for the JSON store method...

                        Anyway! Once you've got that saving we can look at loading the data and re-populating your fields.

                        Do not follow where the path may lead; go instead where there is no path.
                        And leave a trail - Muriel Strode

                        1 Reply Last reply Reply Quote 0
                        • I
                          iperry
                          last edited by iperry

                          Ahh, thanks. I wasn't sure if you could specify where the userModule.js was other than from the public store. I would rather use the overrides directory(s) for my code so I will change the path. I had tried to use this directory before but didn't get the path from the ui quite right.

                          I like the way you segment your code. I have been working with a few MVC frameworks over the years as it fits well with the way I code. Sometimes can be fun trying to trace through code but the modularity is great.

                          I saw your segments for interfacing with the json store and data points. Those are my next stop in this trip. :)

                          Ian

                          1 Reply Last reply Reply Quote 0
                          • Jared WiltshireJ
                            Jared Wiltshire
                            last edited by

                            For anyone that finds this thread, you can create a dialog window in Mango 3.6 very easily -

                            <ma-button label="Show dialog" ng-click="showDialog = {}"></ma-button>
                            
                            <ma-dialog show-dialog="showDialog">
                                <div>This is the dialog content</div>
                            </ma-dialog>
                            

                            Developer at Radix IoT

                            1 Reply Last reply Reply Quote 1
                            • MattFoxM MattFox referenced this topic on
                            • First post
                              Last post