MagicMirror Forum
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • 3rd-Party-Modules
    • Donate
    • Discord
    • Register
    • Login
    A New Chapter for MagicMirror: The Community Takes the Lead
    Read the statement by Michael Teeuw here.

    Query on MMM-CalendarExt3 modification

    Scheduled Pinned Locked Moved Development
    14 Posts 3 Posters 2.3k Views 3 Watching
    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.
    • S Offline
      sdetweil @sdetweil
      last edited by sdetweil

      @sharkbait
      and you can change the pageindicator circles to full button icons thru css

      see
      https://forum.magicmirror.builders/topic/18876/mmm-carousel-pagination-icons/9?_=1735070775315

      Sam

      How to add modules

      learning how to use browser developers window for css changes

      1 Reply Last reply Reply Quote 0
      • M Offline
        MMRIZE @sharkbait
        last edited by MMRIZE

        @sharkbait

        MagicMirror is an open-source project with a modular structure. Modifying the original modules can make updates difficult, so it’s best to avoid it when possible. Fortunately, in CX3, you can easily implement the desired functionality by creating and adding a simple custom module without directly modifying the source code.

        To dynamically change CX3’s view at runtime, you can use the method suggested by sdetweil, which involves creating multiple instances and switching them out one by one. However, this can also be implemented more simply using only notifications.

        The example module below demonstrates how to add two simple buttons to the screen. This module utilizes MagicMirror’s notification architecture to transform CX3’s view when the button is clicked.

        MMM-ButtonExample

        /* modules/MMM-ButtonExample/MMM-ButtonExample.js */
        Module.register("MMM-ButtonExample", {
          getDom: function () {
            const wrapper = document.createElement("div")
            const button1 = document.createElement("button")
            button1.innerHTML = "Current Month"
            button1.onclick = () => {
              this.sendNotification("CX3_RESET", {
                callback: (currentConfig) => {
                  console.log("Return to the original config")
                }
              })
            }
            const button2 = document.createElement("button")
            button2.innerHTML = "Next Month"
            button2.onclick = () => {
              this.sendNotification("CX3_GET_CONFIG", {
                callback: (currentConfig) => {
                  this.sendNotification("CX3_SET_CONFIG", {
                    monthIndex: currentConfig.monthIndex + 1
                  })
                }
              })
            }
            wrapper.appendChild(button1)
            wrapper.appendChild(button2)
            return wrapper
          }
        })
        
        /* config/config.js */
        ...
        {
        	module: "MMM-CalendarExt3",
        	position: "bottom_bar",
        	config: {
        		mode: 'month',
        	}
        },
        {
        	module: "MMM-ButtonExample",
        	position: "bottom_bar",
        },
        ...
        
        

        4c50fc78-ec84-4fce-80a9-02ef23e2bd38-image.png

        S 1 Reply Last reply Reply Quote 0
        • M Offline
          MMRIZE @sharkbait
          last edited by

          @sharkbait
          More polished version.

          386768b6-f517-4340-b8c4-90880e1fdf07-image.png

          MMM-CustomInjection

          /* modules/MMM-CustomInjection/MMM-CustomInjection.js */
          Module.register("MMM-CustomInjection", {
            getStyles: function () {
              return [
                this.file("MMM-CustomInjection.css")
              ]
            },
          
            notificationReceived: function (notification, payload, sender) {
              if (notification === "CX3_DOM_UPDATED") {
                const { instanceId } = payload
                this.inject(instanceId)
              }
            },
          
            inject: function (instanceId) {
              const moduleDom = document.querySelector(`#${instanceId}`)
              if (!moduleDom) return
              moduleDom.classList.add('custom-injected')
              const buttons = document.createElement('div')
              buttons.className = 'calendar-header-buttons'
              const prev = document.createElement('button')
              prev.className = 'calendar-header-button'
              prev.innerHTML = 'PREV'
              prev.onclick = () => {
                this.sendNotification('CX3_GET_CONFIG', {
                  callback: (currentConfig) => {
                    this.sendNotification('CX3_SET_CONFIG', {
                      monthIndex: currentConfig.monthIndex - 1,
                    })
                  }
                })
              }
              const current = document.createElement('button')
              current.className = 'calendar-header-button'
              current.innerHTML = 'CURRENT'
              current.onclick = () => {
                this.sendNotification('CX3_RESET', {})
              }
              const next = document.createElement('button')
              next.className = 'calendar-header-button'
              next.innerHTML = 'NEXT'
              next.onclick = () => {
                this.sendNotification('CX3_GET_CONFIG', {
                  callback: (currentConfig) => {
                    this.sendNotification('CX3_SET_CONFIG', {
                      monthIndex: currentConfig.monthIndex + 1,
                    })
                  }
                })
              }
              buttons.appendChild(prev)
              buttons.appendChild(current)
              buttons.appendChild(next)
              moduleDom.appendChild(buttons)
            }
          })
          
          /* modules/MMM-CustomInjection/MMM-CustomInjection.css */
          .custom-injected {
            position: relative;
          
            .calendar-header-buttons {
              position: absolute;
              top: 30px;
              right: 0;
              display: flex;
              flex-direction: row;
              justify-content: space-between;
              gap: 10px;
              width: fit-content;
          
              .calendar-header-button {
                background-color: transparent;
                border: none;
                color: white;
                font-weight: bold;
              }
            }
          }
          
          S 1 Reply Last reply Reply Quote 0
          • S Offline
            sharkbait @sdetweil
            last edited by

            @sdetweil Thank you for taking the time to read my post and providing the guidance, and the additional modules I could try out. I have tried the 2 extensions as per your recommendation. The transition between pages is slick when set to auto rotate but for some reason, the page indicator module doesn’t allow me to switch (tap) between pages manually on my touchscreen, when I disable the auto-rotate .

            S 1 Reply Last reply Reply Quote 0
            • S Offline
              sharkbait @MMRIZE
              last edited by

              @MMRIZE Thank you for the taking the effort to provide me with the set of code. I’ve tested it and it works wonderfully.

              1 Reply Last reply Reply Quote 0
              • S Offline
                sharkbait @MMRIZE
                last edited by

                @MMRIZE I tried to implement this CustomInjection code but the rendered display turned out like this ![alt text]https://drive.google.com/file/d/1OUJ3EBz1CNMVqA9ds7kQhc4sTuovUoUA/view?usp=sharing.

                My setting in config.js is as follows:
                …,
                {
                module: “MMM-CustomInjection”,
                position: “bottom_bar”,
                },

                Instead of buttons, what I see is just the module name (MMM-CustomInjection, and below that module_5_MMM-CustomInjection).

                This is definitely a more polished solution, but I’m not sure why the display could not be rendered.

                M 1 Reply Last reply Reply Quote 0
                • S Offline
                  sdetweil @sharkbait
                  last edited by

                  @sharkbait
                  and you set

                        rotationTime: 0, 
                  

                  correct??

                  it works for me…

                  and u did change the cursor setting in css… right?

                  Sam

                  How to add modules

                  learning how to use browser developers window for css changes

                  S 1 Reply Last reply Reply Quote 0
                  • S sdetweil referenced this topic on
                  • M Offline
                    MMRIZE @sharkbait
                    last edited by

                    @sharkbait
                    MMM-CustomInjection doesn’t need to be positioned because that module works on background.

                    /* config/config.js */
                    {
                    	module: "MMM-CalendarExt3",
                    	position: "bottom_bar",
                    	config: {
                    		mode: 'month',
                    	}
                    },
                    {
                    	module: "MMM-CustomInjection",
                    },
                    
                    S 1 Reply Last reply Reply Quote 0
                    • S Offline
                      sharkbait @sdetweil
                      last edited by sdetweil

                      @sdetweil I added this entry to custom.css:

                      html {
                        cursor: default;
                      }
                      

                      For config.js, my settings for “MMM-CalendarExt3”, “MMM-pages” and “MMM-page-indicator” were as follows:

                      	{
                      		  module: "MMM-CalendarExt3",
                      		  position: "bottom_bar",
                      		  classes:"page3",
                      		  title: "Our Family Calendar",
                      		  config: {
                      			mode: "month",
                      			headerWeekDayOptions: {
                      				weekday: "narrow"
                      			},
                      			cellDateOptions: { day: 'numeric' }, // suppress month from appear in cellDate
                      			monthIndex: 0, //0=curr_month, -1=prev, 1=next
                      			maxEventLines: {0:6, 6:5}, 
                      			firstDayOfWeek: 0,
                      			calendarSet: [],
                      			fontSize: '18px',
                      			refreshInterval: 120000,
                      		  },
                      		  disabled: false,
                      	},
                      
                      		  {
                      			module: "MMM-page-indicator",
                      			position: "bottom_bar",
                      			order: "*",
                      			config: {},
                      			disabled: false,
                      			classes: "fixed"
                      		  },
                      	// pages
                      		  {
                      			module: "MMM-pages",
                      			disabled: false,
                      			config: {
                      			  modules: [
                      				[
                      				  "page1"
                      				],
                      				[
                      				  "page2"
                      				],
                      				[
                      				  "page3"
                      				]
                      			  ],
                      			  fixed: [
                      				"fixed"
                      			  ],
                      			  animationTime: 10000, // time of fade in/out on page change
                      			  rotationTime: 0,  // if you make this 0, then the pages only turn manually or via notification from somewhere else (indicator)
                      			  hiddenPages: {
                      			  }
                      			},
                      			order: "*"
                      		  },
                      

                      A white circular dot at the bottom indicates whether the rendered page is page1 or page2 or page3. I tried tapping on the white dots but wasn’t able to switch among page views. Could it be a touchscreen (portrait orientation) xinput issue ?

                      S 1 Reply Last reply Reply Quote 0
                      • S Offline
                        sharkbait @MMRIZE
                        last edited by

                        @MMRIZE I’ve removed the position of the “MMM-CustomInjection” module from the config.js as per your kind advice. The 3 buttons [prev], [current ] and [next] are still not appearing in the Calendar HeaderTitle (i.e. in my case -> DECEMBER 2024).

                        This settings for my config.js are as follows:

                        ...,
                        		{
                        		  module: "MMM-CalendarExt3",
                        		  position: "bottom_bar",
                        		  title: "Our Family Calendar",
                        		  config: {
                        			mode: "month",
                        			cellDateOptions: { day: 'numeric' }, // suppress month from appear in cellDate
                        			monthIndex: 0, //0=curr_month, -1=prev, 1=next
                        			instanceId: "basicCalendar",
                        			maxEventLines: {0:6, 6:5}, // Dynamically sized; 5 events for months with 6 weeks. 6 events for all others.
                        			firstDayOfWeek: 0,
                        			calendarSet: [],
                        			fontSize: '18px',
                        		  }
                        		},
                        
                        		{
                        			module: "MMM-CustomInjection",
                        		}, ...
                        
                        

                        The code deployed for the MMM-CustomInjection.js was:

                        /* modules/MMM-CustomInjection/MMM-CustomInjection.js */
                        Module.register("MMM-CustomInjection", {
                          getStyles: function () {
                            return [
                              this.file("MMM-CustomInjection.css")
                            ]
                          },
                        
                          notificationReceived: function (notification, payload, sender) {
                            if (notification === "CX3_DOM_UPDATED") {
                              const { instanceId } = payload
                              this.inject(instanceId)
                            }
                          },
                        
                          inject: function (instanceId) {
                            const moduleDom = document.querySelector(`#${instanceId}`)
                            if (!moduleDom) return
                            moduleDom.classList.add('custom-injected')
                            const buttons = document.createElement('div')
                            buttons.className = 'calendar-header-buttons'
                            const prev = document.createElement('button')
                            prev.className = 'calendar-header-button'
                            prev.innerHTML = 'PREV'
                            prev.onclick = () => {
                              this.sendNotification('CX3_GET_CONFIG', {
                                callback: (currentConfig) => {
                                  this.sendNotification('CX3_SET_CONFIG', {
                                    monthIndex: currentConfig.monthIndex - 1,
                                  })
                                }
                              })
                            }
                            const current = document.createElement('button')
                            current.className = 'calendar-header-button'
                            current.innerHTML = 'CURRENT'
                            current.onclick = () => {
                              this.sendNotification('CX3_RESET', {})
                            }
                            const next = document.createElement('button')
                            next.className = 'calendar-header-button'
                            next.innerHTML = 'NEXT'
                            next.onclick = () => {
                              this.sendNotification('CX3_GET_CONFIG', {
                                callback: (currentConfig) => {
                                  this.sendNotification('CX3_SET_CONFIG', {
                                    monthIndex: currentConfig.monthIndex + 1,
                                  })
                                }
                              })
                            }
                            buttons.appendChild(prev)
                            buttons.appendChild(current)
                            buttons.appendChild(next)
                            moduleDom.appendChild(buttons)
                          }
                        })
                        

                        The accompanying “MMM-CustomInjection.css” settings were:

                        /* modules/MMM-CustomInjection/MMM-CustomInjection.css */
                        .custom-injected {
                          position: relative;
                        
                          .calendar-header-buttons {
                            position: absolute;
                            top: 30px;
                            right: 0;
                            display: flex;
                            flex-direction: row;
                            justify-content: space-between;
                            gap: 10px;
                            width: fit-content;
                        
                            .calendar-header-button {
                              background-color: transparent;
                              border: none;
                              color: white;
                              font-weight: bold;
                            }
                          }
                        }
                        
                        M 1 Reply Last reply Reply Quote 0
                        • S Offline
                          sdetweil @sharkbait
                          last edited by sdetweil

                          @sharkbait said in Query on MMM-CalendarExt3 modification:

                          A white circular dot at the bottom indicates whether the rendered page is page1 or page2 or page3. I tried tapping on the white dots but wasn’t able to switch among page views. Could it be a touchscreen

                          I don’t know… but we can find out pretty easily , using the developers window…

                          start mm
                          using the keyboard on the MM screen, open the developers window, ctrl-shift-i
                          (or use npm start dev to open from the commandline, don’t use pm2)
                          select the elements tab and then click the arrow on top left

                          then click one of the circles…
                          that should open the document view with the buttons selected

                          Screenshot at 2024-12-30 07-37-15.jpg

                          you can expand the sections to show the buttons (<a)

                          now select the sources tab, expand modules in left nav, select MMM-PageIndicator, select MMM-PagIndicator.js, its source should appear in the right pane

                          scroll down and click on the number on line 66, it should highlight, like this
                          Screenshot at 2024-12-30 07-38-17.jpg

                          now click one of the page indicator buttons… mouse or finger

                          it should show and stop on the line 66 instruction
                          Screenshot at 2024-12-30 07-47-17.jpg

                          if it did then it is operating
                          if it didn’t… hmm…

                          if it stopped, click the line 66 again , and the highlight will be removed, and then push the blue arrow on the top right, to continue the application

                          I will test on my touch screen laptop, no expectation that it will fail.
                          mm is just a page in a browser… nothing special.(from an OS perspective)

                          edit: tested on my laptop, worked with mouse and touch as expected
                          edit: ctrl-shift-i to close the developer window

                          Sam

                          How to add modules

                          learning how to use browser developers window for css changes

                          1 Reply Last reply Reply Quote 0
                          • M Offline
                            MMRIZE @sharkbait
                            last edited by

                            @sharkbait
                            Your CX3 may not be the latest version.(1.9.4)

                            1 Reply Last reply Reply Quote 0

                            Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                            Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                            With your input, this post could be even better 💗

                            Register Login
                            • 1 / 1
                            • First post
                              Last post
                            Enjoying MagicMirror? Please consider a donation!
                            MagicMirror created by Michael Teeuw.
                            Forum managed by Sam, technical setup by Karsten.
                            This forum is using NodeBB as its core | Contributors
                            Contact | Privacy Policy