Something about UI

Hi all,

I have 2 questions on web UI.

  1. I have a kind of menu with a couple of selections in which I use WebImageView to present as buttons. Each “button” has 2 images to simulate hover effect, default I show image A, when mouse in, I show image B, mouse out, show image A again. I used to use WebCanvas instead of WebImage, just don’t why when using WebCanvas, exceptions raised (not every time, maybe once per 10 times) which I don’t know how to handle. How do you guys handle this?

  2. I would like to put notification on a “button”, I will have a timer in the webpage to poll for new messages. If there is, I would like to put a number inside a red circle to represent unread messages. Is WebCanvas the only way to do this? How to remove the notification when there is no more new message?

Thanks in advance for your advise.

For a badge (the red circle with the number is called a badge), you can perfectly well draw it into an image that you display in your ImageView. Or place a small canvas over, especially for that purpose.

Thanks Michel, I learn more again.

I do tried to use canvas to show badge, and I tried now again. It still raises exceptions which I do not understand:

Could not execute returned javascript: Cannot read property ‘refresh’ of undefined
Source: window.GSjQuery(’#yqdekJ08 .fc-sun’).addClass(‘StyleTextColorRed’);
window.GSjQuery(’#yqdekJ08 .fc-toolbar’).addClass(‘StyleCalendar’);
window.GSjQuery(’#yqdekJ08 .fc-toolbar button’).addClass(‘StyleCalendar2’);
window.GSjQuery(‘head’).append(’<link rel=\‘stylesheet\’ id=\‘gwcal_yqdekJ08_theme\’ href=\’\’>’ );suppLang = [];window.GSjQuery.each(window.GSjQuery.fullCalendar.locales, function(langCode) {suppLang.push(langCode);});Xojo.triggerServerEvent(‘yqdekJ08’,‘LanguagesLoaded’, suppLang);window.GSjQuery(’#yqdekJ08’).fullCalendar({header: {left: ‘prevYear,nextYear’,center: ‘prev title next’,right: ‘month,agendaWeek,agendaDay’},theme: false,locale: ‘zh-tw’,defaultDate: ‘2017-06-29’,defaultView: ‘month’,editable: true,eventLimit: true,eventLimitClick: ‘popover’,eventLimitText: ‘more’,height: ‘100%’,selectable: true,selectionHelper: true,viewRender: function( view, element ) {Xojo.triggerServerEvent(‘yqdekJ08’,‘ViewChanged’, [view.name,view.start.get(‘year’),view.start.get(‘month’) + 1,view.start.get(‘date’), view.start.get(‘hour’),view.start.get(‘minute’),view.start.get(‘second’),view.end.get(‘year’),view.end.get(‘month’) + 1,view.end.get(‘date’), view.end.get(‘hour’),view.end.get(‘minute’),view.end.get(‘second’),view.start.hasTime(),view.end.hasTime()]);},select: function (start, end, jsEvent, view) {if( typeof(jsEvent) != ‘undefined’ ) {Xojo.triggerServerEvent(‘yqdekJ08’,‘Selected’, [‘month’,start.get(‘year’),start.get(‘month’) + 1,start.get(‘date’), start.get(‘hour’),start.get(‘minute’),start.get(‘second’),end.get(‘year’),end.get(‘month’) + 1,end.get(‘date’), end.get(‘hour’),end.get(‘minute’),end.get(‘second’),start.hasTime(),end.hasTime()]);}},googleCalendarError: function(e) {Xojo.triggerServerEvent(‘yqdekJ08’, ‘googleCalendarError’, [e.domain,e.reason,e.message]);},eventDragStart: function(event,jsevent,ui,view) {},eventDragStop: function(event,jsevent,ui,view) {},eventClick: function(data,jsEvent,view) {window.graffwebcalyqdekJ08clickevent = data;if( typeof(data.url) !== ‘undefined’) {window.open(data.url, ‘gcalevent’, ‘width=700,height=600’);return false;} else {Xojo.triggerServerEvent(‘yqdekJ08’,‘EventClick’, [data.id,data.title]);}},eventMouseover: function( data, jsEvent, view ) {Xojo.triggerServerEvent(‘yqdekJ08’,‘EventHover’, [data.id,data.title,jsEvent.pageX,jsEvent.pageY]);},eventDrop: function( event, delta, revertFunc, jsEvent, ui, view ) {Xojo.triggerServerEvent(‘yqdekJ08’,‘EventDrop’, [event.id,event.start.get(‘year’),event.start.get(‘month’) + 1,event.start.get(‘date’), event.start.get(‘hour’),event.start.get(‘minute’),event.start.get(‘second’),event.end.get(‘year’),event.end.get(‘month’) + 1,event.end.get(‘date’), event.end.get(‘hour’),event.end.get(‘minute’),event.end.get(‘second’),event.start.hasTime()]);window.GSjQuery(’#yqdekJ08’).fullCalendar(‘rerenderEvents’);},eventResize: function( event, delta, revertFunc, jsEvent, ui, view ) {Xojo.triggerServerEvent(‘yqdekJ08’,‘EventResize’, [event.id,event.start.get(‘year’),event.start.get(‘month’) + 1,event.start.get(‘date’), event.start.get(‘hour’),event.start.get(‘minute’),event.start.get(‘second’),event.end.get(‘year’),event.end.get(‘month’) + 1,event.end.get(‘date’), event.end.get(‘hour’),event.end.get(‘minute’),event.end.get(‘second’),event.start.hasTime()]);window.GSjQuery(’#yqdekJ08’).fullCalendar(‘rerenderEvents’);},eventMouseout: function( data, jsEvent, view ) {Xojo.triggerServerEvent(‘yqdekJ08’,‘EventMouseOut’, [data.id,data.title]);},});
myInner = window.GSjQuery(’#yqdekJ08’);if( typeof(myInner) != ‘undefined’ ) {if( typeof(myInner.fullCalendar) == ‘function’ ) {parentPx = myInner.getDefaultPx(2);var toolbar = window.GSjQuery(’#yqdekJ08 .fc-toolbar’);if( typeof(toolbar) != ‘undefined’ ) {var toolHeight = toolbar.height();var fullHeight = (myInner.height() - toolHeight);window.GSjQuery(’#yqdekJ08’).fullCalendar(‘option’, ‘contentHeight’, fullHeight - 5);}}}myInner = window.GSjQuery(’#yqdekJ08’);if( typeof(myInner) != ‘undefined’ ) {if( typeof(myInner.fullCalendar) == ‘function’ ) {parentPx = myInner.getDefaultPx(2);var toolbar = window.GSjQuery(’#yqdekJ08 .fc-toolbar’);if( typeof(toolbar) != ‘undefined’ ) {var toolHeight = toolbar.height();var fullHeight = (myInner.height() - toolHeight);window.GSjQuery(’#yqdekJ08’).fullCalendar(‘option’, ‘contentHeight’, fullHeight - 5);}}}myInner = window.GSjQuery(’#yqdekJ08’);if( typeof(myInner) != ‘undefined’ ) {if( typeof(myInner.fullCalendar) == ‘function’ ) {parentPx = myInner.getDefaultPx(2);var toolbar = window.GSjQuery(’#yqdekJ08 .fc-toolbar’);if( typeof(toolbar) != ‘undefined’ ) {var toolHeight = toolbar.height();var fullHeight = (myInner.height() - toolHeight);window.GSjQuery(’#yqdekJ08’).fullCalendar(‘option’, ‘contentHeight’, fullHeight - 5);}}}window.GSjQuery(’#yqdekJ08’).css(‘visibility’,‘visible’).css(‘display’,‘block’);window.GSjQuery(’#yqdekJ08’).fullCalendar(‘changeView’,‘month’);myInner = window.GSjQuery(’#yqdekJ08’);if( typeof(myInner) != ‘undefined’ ) {if( typeof(myInner.fullCalendar) == ‘function’ ) {parentPx = myInner.getDefaultPx(2);var toolbar = window.GSjQuery(’#yqdekJ08 .fc-toolbar’);if( typeof(toolbar) != ‘undefined’ ) {var toolHeight = toolbar.height();var fullHeight = (myInner.height() - toolHeight);window.GSjQuery(’#yqdekJ08’).fullCalendar(‘option’, ‘contentHeight’, fullHeight - 5);}}}myInner = window.GSjQuery(’#yqdekJ08’);if( typeof(myInner) != ‘undefined’ ) {if( typeof(myInner.fullCalendar) == ‘function’ ) {parentPx = myInner.getDefaultPx(2);var toolbar = window.GSjQuery(’#yqdekJ08 .fc-toolbar’);if( typeof(toolbar) != ‘undefined’ ) {var toolHeight = toolbar.height();var fullHeight = (myInner.height() - toolHeight);window.GSjQuery(’#yqdekJ08’).fullCalendar(‘option’, ‘contentHeight’, fullHeight - 5);}}}window.GSjQuery(’#yqdekJ08’).fullCalendar(‘removeEvents’);
Xojo.controls[‘uSXQI9Zd’].refresh();

P.S. I have a WebCalendar from Graffiti on the same page. I use a timer to periodically check if new messages for the user and show the badge if there is. I do not have any JavaScript from my own.

The error does not tell much, except apparently you are trying to access an unexisting element.

You should try drawing on the badge on a new project without anything else first, make sure it works, and then only move it to your main project.

Seems GraffitiSuite is definitely doing something odd :
https://forum.xojo.com/41574-exception-raised-when-canvas-meet-graffitisuite-webcalendar

As mentioned in my other post, if the WebCanvas and the WebCalendar do not co-exists, no problem arises.