Select to view content in your preferred language

Custom button onclick takes effect on onmouseout

5289
13
Jump to solution
11-28-2018 01:39 PM
ElizabethMiller
Regular Contributor

I have a custom panel widget in WAB Developer edition. On the panel is a dijit/form/Button. It has a css class that gives it a color. It also has a label "Start Tool." There is a data-dojo-attach-event = "onClick:mytogglefunction."

In my widget code I have mytogglefunction, which uses an if/else pattern to look for the label state and change it to a different label "Stop Tool" and also change the css class (so button gets a different color when clicked and activated.)

Problem: user clicks once on button. Label changes immediately onclick, but css color doesn't change until the mouse pointer rolls off the button. So there are essentially 2 events happening -- the click, then the onmouseout. 

As I understand it, this is not a css :hover problem. I want the css to update on one onclick.

I created a similar button in a CMV application that worked fine -- but I don't know what is controlling this behavior in WAB.

Help! Thank you!

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Elizabeth,

   Here is what I tested in your scenario and works:

      mytogglefunction: function(){
        //toggleButton
        if (this.toggleButton.label == 'Start Tool'){
          this.toggleButton.set('label', 'Stop Tool');
          domClass.replace(this.toggleButton.domNode, 'success', 'danger');
          this.map.setMapCursor('crosshair');
        } else if (this.toggleButton.label == 'Stop Tool'){
          domClass.replace(this.toggleButton.domNode, 'danger', 'success');
          this.toggleButton.set('label', 'Start Tool');
          this.map.setMapCursor('default');
        }
      },

View solution in original post

13 Replies
RobertScheitlin__GISP
MVP Emeritus

Can I see your mytogglefunction code?

0 Kudos
ElizabethMiller
Regular Contributor

Robert,

Here is the function. 

mytogglefunction: function () {
           
     if (this.toggleButton.label == 'Start Tool'){
     this.toggleButton.set('label', 'Stop Tool');               
     this.toggleButton.set('baseClass', 'success');
     this.map.setMapCursor('crosshair');
     this.createToolbar();
                    
        } else if (this.toggleButton.label == 'Stop Tool'){
     this.toggleButton.set('baseClass', 'danger');
     this.toggleButton.set('label', 'Start Tool');
     this.map.setMapCursor('default');
     this.defmapClickEvtHandler.remove();
                    
     this.map.graphics.clear();
     this.map.infoWindow.hide();
     this.map.removeLayer(allHwys);
     this.gtoolbar.deactivate(); 
               
            }
        },     

Here is one of the css styles:

.success .dijitButtonNode {
    background: #000000;
    border-color: #000000;
    color: #FFF;
    padding: 6px 6px;
    font-weight: bold;
    border-style: solid;
    border-width: 2px;
    border-radius: 6px;
     
     
}
0 Kudos
ElizabethMiller
Regular Contributor

I have resorted to a workaround.

I didn't make any progress with getting the button to change color immediately on onClick using the css class. The class was updated only after the mouse was moved off the button. Then the color change would take effect. This problem was magnified on a phone, where the user would have to tap twice to get the button to change color.

My workaround is I am changing the color directly in mytogglefunction. It changes the button immediately onclick and works on a phone too.

I'm still interested in figuring out why the button onclick wouldn't immediately change my style, if you have any ideas.

Here's my workaround:

domStyle.set("mybutton", {
     background: "#000000",
     borderstyle: "solid",
     borderwidth: "2px",
     borderradius: "6px"
                         
});
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Elizabeth,

   Your issue was you where trying to set the baseClass for the button instead of using domClass.replace("mybutton", "danger", "sucess");

or domClass.add('mybutton, 'danger');

0 Kudos
ElizabethMiller
Regular Contributor

That does not work for me unfortunately!

I tried

domClass.replace("mybutton", "success", "danger");

in my code but now the css class isn't changing at all (I tried changing the order of the 2 classes parameters in case I had it wrong!)

Maybe I am setting up the button wrong in my html template? For what it's worth, here's what I have there. (I tried making the element a <button> rather than a <div> but it didn't seem to make a difference.

Thanks again.

<div data-dojo-attach-point="_contentPanel">

<div style="text-align:center">

<div style="padding:5px">


<div data-dojo-type="dijit/form/Button" id="mybutton" data-dojo-props="label:'Start Tool', baseClass:'danger'" data-dojo-attach-event="onClick:mytogglefunction" data-dojo-attach-point="toggleButton">
</div>

</div>

</div>

</div>

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Elizabeth,

   Here is what I tested in your scenario and works:

      mytogglefunction: function(){
        //toggleButton
        if (this.toggleButton.label == 'Start Tool'){
          this.toggleButton.set('label', 'Stop Tool');
          domClass.replace(this.toggleButton.domNode, 'success', 'danger');
          this.map.setMapCursor('crosshair');
        } else if (this.toggleButton.label == 'Stop Tool'){
          domClass.replace(this.toggleButton.domNode, 'danger', 'success');
          this.toggleButton.set('label', 'Start Tool');
          this.map.setMapCursor('default');
        }
      },
ElizabethMiller
Regular Contributor

Thanks again -- something about my setup is still not working. I am not sure how the button id and the data-dojo-attach-point are being used and I think something is getting confused. Why is the data-dojo-attach-point for my button text (on line 7) showing up as "containerNode"? Also, in my example of the workaround I gave above, for example, the way it works is that it is changing the color of the background of the textbox, not the button itself. I don't understand this, since I thought the attach point and the id both refer to the button element I created. The workaround works because it changes the background color of the text immediately on click, whereas every attempt to change the css of the button still only works onmouseout.

Using your code snippet in my setup results in a confusion of classes (but still with the onmouseout problem). I've tried to show more by copying some of the code from the Chrome elements panel.

Here's what I see before clicking on the button:

<span class="dijit dijitReset dijitInline danger" role="presentation" widgetid="mybutton">
<span class="dijitReset dijitInline dijitButtonNode" data-dojo-attach-event="ondijitclick:__onClick" role="presentation">
<span class="dijitReset dijitStretch dijitButtonContents" data-dojo-attach-point="titleNode,focusNode" role="button" aria-labelledby="mybutton_label" tabindex="0" id="mybutton" style="user-select: none;">
<span class="dijitReset dijitInline dijitIcon dijitNoIcon" data-dojo-attach-point="iconNode">
</span>
<span class="dijitReset dijitToggleButtonIconChar">●</span>
<span class="dijitReset dijitInline dijitButtonText" id="mybutton_label" data-dojo-attach-point="containerNode">Start Tool</span>
</span>
</span>
<input type="button" value="" class="dijitOffScreen" data-dojo-attach-event="onclick:_onClick" tabindex="-1" aria-hidden="true" data-dojo-attach-point="valueNode">
</span>

After 1 click on the button -- there is no change except the text changes to "Stop Tool."

Here's what I see after 2 clicks -- confusion of classes and the text changes back to "Start Tool."

<span class="dijit dijitReset dijitInline success danger" role="presentation" widgetid="mybutton">
<span class="dijitReset dijitInline dijitButtonNode" data-dojo-attach-event="ondijitclick:__onClick" role="presentation">
<span class="dijitReset dijitStretch dijitButtonContents" data-dojo-attach-point="titleNode,focusNode" role="button" aria-labelledby="mybutton_label" tabindex="0" id="mybutton" style="user-select: none;">
<span class="dijitReset dijitInline dijitIcon dijitNoIcon" data-dojo-attach-point="iconNode">
</span>
<span class="dijitReset dijitToggleButtonIconChar">●</span>
<span class="dijitReset dijitInline dijitButtonText" id="mybutton_label" data-dojo-attach-point="containerNode">Start Tool</span>
</span>
</span>
<input type="button" value="" class="dijitOffScreen" data-dojo-attach-event="onclick:_onClick" tabindex="-1" aria-hidden="true" data-dojo-attach-point="valueNode">
</span>
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Elizabeth,

  Dom Ids are Not used in best practice templated widget development. the data-dojo-attach-point is what you will use to get a reference to the dom element in the template.

 When I used this in my widgets template.html and used the code I last provided the button color changed immediately:

<div data-dojo-type="dijit/form/Button" data-dojo-props="label:'Start Tool', baseClass:'danger'" data-dojo-attach-event="onClick:mytogglefunction" data-dojo-attach-point="toggleButton"></div>‍‍

The only thing I removed was the id property. I am not sure what is going wrong with your implementation of my code. Maybe you can zip your whole widget and attach it (using the advanced editor) for me to look at.

0 Kudos
ElizabethMiller
Regular Contributor

Problem solved! 

Maybe it's not the best way, but this is now working perfectly for me. I kept both the code I originally had and added your suggestion to it. That did the trick.

Hopefully it's not too ugly!

mytogglefunction: function(){
        //toggleButton
        if (this.toggleButton.label == 'Start Tool'){
          this.toggleButton.set('label', 'Stop Tool');
          this.toggleButton.set('baseClass', 'success');
          domClass.replace(this.toggleButton.domNode, 'success', 'danger');
          this.map.setMapCursor('crosshair');
        } else if (this.toggleButton.label == 'Stop Tool'){
          this.toggleButton.set('baseClass', 'danger');
          domClass.replace(this.toggleButton.domNode, 'danger', 'success');
          this.toggleButton.set('label', 'Start Tool');
          this.map.setMapCursor('default');
        }
      },‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos