VueJS - How to highlight selected button when clicked - vue.js

I have 3 buttons that shows a chart when clicked on it respectively. Here below is the buttons for example:
Whenever the button is clicked respective chart is shown, but I want to keep the button highlighted with red color while the chart is shown.
<vs-button color="warning" #click="chartClick($event, 'chart1')" vs-value="chart1" v-model="show"> chart1</vs-button>
<vs-button color="warning" #click="chartClick($event, 'chart2')" vs-value="chart2" v-model="show"> chart2 </vs-button>
<vs-button color="warning" #click="chartClick($event, 'chart3')" vs-value="chart3" v-model="show"> chart3 </vs-button>
<script>
data () {
return {
show = false
}
},
mounted (){
chartClick (chart1)
},
methods: {
chartClick (event, id){
...
this.show = true
}
}
</script>
Please help me in this, i want to know how to highlight the button, when the chart is shown.
And also i want to know how to display chart1 with button1 (chart1) highlighted when the page is loaded or runned at first.

You can do that by adding one more variable in data section, for example:
data () {
return {
show : false,
activeChart : '',
}
}
You should not use variableName = defaultValue, it should be variableName : defaultValue.
and then add to your buttons:
:class="{activeChartClass: activeChart === 'chart1'}"
Note: are you sure v-model is supported on vs-button tag?
also you will have to add this to your chartClick method:
this.activeChart = id;
and finally add a CSS class to edit your active button:
.activeChartClass {
background-color: red!important;
}
You can read more about class and style binding here: https://v2.vuejs.org/v2/guide/class-and-style.html#Object-Syntax

Related

PrimeNg TabView with ConfirmDialog not working

I'm trying to use PrimeNg TabView component along with confirmDialog unsuccessfully
I am able to show this confirm dialog but it appears after user switch to target tab panel which is wrong.
<p-tabView (onChange)="handleChange($event)" [(activeIndex)]="index">...</p-tabView>
handleChange(e) {
this.confirmationService.confirm({
message: 'There are unsaved changes, do you want to proceed?',
accept: () => {
this.index = e.index;
},
reject:() =>{ }
});
}
Do you have an idea on how to prevent or allow tab change using confirm dialog ?
Thanks
there is no official way to prevent change to another tab by press on that tab , but 😅 there is a work around it first we need to prevent the tab change by tab click,
1️⃣ we need to set the header by ng-template or it called a custom header
template
<p-tabPanel >
<ng-template pTemplate="header">
<div (click)="handleChange($event,0)">
Godfather I
</div>
</ng-template>
.....
</p-tabPanel>
2️⃣ we bind a click event to the new header text and by using mouse event stopPropagation method we can prevent the change 👌,now we can control the change by confirm result but you need to pass the current tab index, that why I add another parameter to handleChange
component
handleChange(e:MouseEvent,tabIndex:number) {
e.stopPropagation();
if (this.index == tabIndex){
return;
}
// console.log(tabIndex)
this.confirmationService.confirm({
message: "There are unsaved changes, do you want to proceed?",
accept: () => {
this.index = tabIndex;
},
reject: () => {}
});
}
the if block if (this.index == tabIndex){return;} use to prevent showing the confirm dialog if we click on the same active tab again
demo 🚀🚀

canvasOverlay show in jqplot

How do I trigger on the overlays in jqplot only after I click a checkbox (not when the html loads). When I first set overlay option show to false the overlays are not displayed on plot at 1st and when I used my trigger function the overlays do not appear.
Here is the code I use for the plot :
<div id="fastest" style="margin-top:20px; margin-left:20px; margin-right:200px; width:800px; height:400px;">
<script class="code" type="text/javascript">
$(document).ready(function(){
var dataset="too long to be displayed here"
plot1 = $.jqplot('fastest', dataset, {
title: 'Test_figs',
legend: {show:false},
series: [{
showMarker: false,
color: '#ED0E0E',
label: 'R spectrum',
neighborThreshold: -1
}],
axes:{
xaxis:{
label:'Restframe Wavelength'
},
yaxis:{
label:'Flux',
tickOptions:{formatString:'%.3e'}
}
},
cursor:{
show:true,
zoom:true,
tooltipLocation:'sw'
},
Canvasoverlay: {
show: false,
objects: [
{verticalLine: {
name: 'Na-ID',
x: 5893.000000,
lineWidth: 2,
color: '#F0630C',
lineCap:'butt',
yOffset:0,
shadow: true
}}
]
}
});
});
function NaID_trigger() {
var co = plot1.plugins.canvasOverlay;
var line = co.get('Na-ID');
if (line.options.show==false) line.options.show = true;
else line.options.show = false;
co.draw(plot1);
}
</script>
I then use :
<button onclick="NaID_trigger()">Na-ID</button>
to trigger the overlay on or off for instance.
PS: I tried replacing draw by replot as advised didn't work when show=false in overlays options.
I finally found the solution myself :
to not display the overlays when the jqplot loads I set the overall overlays "show" option to true.
Then within each object I set show to false.
Instead of the external to the plot function I used before I switched to an even handler of the form:
$("input[type=checkbox][name=Na-ID]").change(function(){
plot1.plugins.canvasOverlay.get('Na-ID').options.show = this.checked;
plot1.replot();
});
Now the plot display the selected overlay when checkbox is ticked and not at the beginning.
Hope this will help someone who has the same issues.

Dijit.tree extension with radio buttons submitting the wrong value

I've written a class that extends dijit.Tree to include a radio button alongside each node. I'm using it in a form to show a folder tree from which the user can select a folder. Here is the code:
define("my/Tree/RadioButton",
['dojo/_base/declare', 'dijit/Tree', 'dijit/form/RadioButton', 'dojo/dom-construct', 'dojo/_base/connect', 'dojo/on', 'dojo/_base/lang'],
function (declare, Tree, RadioButton, domConstruct, connect, on, lang){
var TreeNode = declare(Tree._TreeNode, {
_radiobutton: null,
postCreate: function(){
this._createRadioButton();
this.inherited(arguments);
},
_createRadioButton: function(){
this._radiobutton = new RadioButton({
name: this.tree.name,
value: this.tree.model.store.getIdentity(this.item) + '',
checked: false
});
domConstruct.place(this._radiobutton.domNode, this.iconNode, 'before');
if (this.tree.model.store.hasAttribute(this.item, 'checked')) {
var attrValue = this.tree.model.store.getValue(this.item, 'checked');
if (attrValue === true) {
this._radiobutton.set('checked', true);
}
}
connect.connect(this._radiobutton, 'onClick', this, function(){
// set any checked items as unchecked in the store
this.tree.model.store.fetch({
query: {checked: true},
onItem: lang.hitch(this.tree.model.store, function(item){
console.log('found checked item ' + this.getValue(item, 'name'));
this.setValue(item, 'checked', false);
})
});
// check the one that was clicked on
var radioValue = this._radiobutton.get('value');
this.tree.model.store.setValue(this.item, 'checked', true);
});
}
});
return declare(Tree, {
_createTreeNode: function(/*Object*/ args){
return new TreeNode(args);
}
});
});
The issue is that when the form is submitted, the value that is submitted is always the value of the first radio button that was selected, even if other radio buttons are subsequently clicked on.
I can see by inspecting the dom that the value attribute for the checked radio button has the correct value. But what gets submitted is always the initially selected value.
I have a similar class that uses the checkbox widget instead and that one works fine.
Edit based on some feedback I created an even simpler version of this class that doesn't track the checked state using attribute in the store:
define("my/Tree/RadioButton",
['dojo/_base/declare', 'dijit/Tree', 'dijit/form/RadioButton', 'dojo/dom-construct'],
function (declare, Tree, RadioButton, domConstruct){
var TreeNode = declare(Tree._TreeNode, {
_radiobutton: null,
postCreate: function(){
this._createRadioButton();
this.inherited(arguments);
},
_createRadioButton: function(){
this._radiobutton = new RadioButton({
name: this.tree.name,
value: this.tree.model.store.getIdentity(this.item) + '',
checked: false
});
domConstruct.place(this._radiobutton.domNode, this.iconNode, 'before');
}
});
return declare(Tree, {
_createTreeNode: function(/*Object*/ args){
return new TreeNode(args);
}
});
});
but even this still has the same issue - whichever radio button the user clicks on first is the value that will be submitted, regardless of what other buttons are subsequently clicked.
I managed to workaround this issue by hooking on to the onchange event for the radio buttons. The hook explicitly sets checked to false on the unchecked radio button, which seems to fix the problem. I'm unsure why this is required though.
I have this exact same problem. It used to work in older Dojos. Specifically, ALL of the radioButtons incorrectly return true on "dijit.byId("whatever").checked" during the onClicked function. When checked manually after the onClicked function finishes using FireBug console, the above property returns the correct values. I think it is a bug, and I only worked around it by having a different onClicked function for each button, like so:
<form id="locateForm">
<label for="locate">Locate:</label><br />
<input type="radio" dojoType="dijit.form.RadioButton" name="locate" id="locateAddress" value="Address" checked="checked" onClick="enableLocate1();" />
<label for="locateAddress">Address</label>
<input type="radio" dojoType="dijit.form.RadioButton" name="locate" id="locatePlace" value="Place" onClick="enableLocate2();" />
<label for="locatePlace">Place</label>
</form>

onfocus event not firing on dojo dijit FilteringSelect

I have a page with 7 dijit FilteringSelect widgets that I want to connect to stores fetched from the server if the user clicks on the widget or the widget otherwise gains focus. I want the event to fire one time.
If I add onfocus="loadDropDown(this)" to my markup, it executes every time the widget gains focus, as you would expect.
I'm trying to use dojo to fire the event one time using on.once(). The function to use dojo event handling is running but the event handler function never gets called when a widget gains focus.
Any pointers?
This is my markup
<select data-dojo-type="dijit.form.FilteringSelect"
type="text" intermediateChanges="false"
data-dojo-props="required:false, pageSize:20, placeholder: '---'"
scrollOnFocus="true" name="CJ1lxA" style="width: 40em;"
id="searchAgency">
</select>
This is to regester the events
function registerDDLoad(){
require(["dojo/on", "dijit", "dojo/ready"], function(on, dijit, ready){
ready(function(){
var dropDown = dijit.byId("searchAgency");
on.once(dropDown, "onfocus", function() {
loadDropDown(dropDown);
});
dropDown = dijit.byId("searchLocation");
on.once(dropDown, "onfocus", function() {
loadDropDown(dropDown);
});
dropDown = dijit.byId("searchCounty");
on.once(dropDown, "onfocus", function() {
loadDropDown(dropDown);
});
dropDown = dijit.byId("searchRep");
on.once(dropDown, "onfocus", function() {
loadDropDown(dropDown);
});
dropDown = dijit.byId("searchSenate");
on.once(dropDown, "onfocus", function() {
loadDropDown(dropDown);
});
dropDown = dijit.byId("searchStatus");
on.once(dropDown, "onfocus", function() {
loadDropDown(dropDown);
});
dropDown = dijit.byId("searchAE");
on.once(dropDown, "onfocus", function() {
loadDropDown(dropDown);
});
});
});
}
registerDDLoad();
The dojo event class, dojo/on expects events to be specified without the 'on':
onFocus = focus
onClick = click
onMouseOut = mouseout
...
I think changing that should fix your problem. I've copied your code into test area on jsFiddle, so you can play around with it.
NB: Since you are re-using the dropdown variable, it will always equal the last filteringSelect (id=searchAE) and never the earlier ones.

How to position a dijit.menu relative to its trigger?

I've got a couple menus like this:
// Contextual Menu
// triggers
<div id="contextMenuTrigger0">0</div>
<div id="contextMenuTrigger1">1</div>
// menu
<div dojoType="dijit.Menu"
targetNodeIds="contextMenuTrigger0, contextMenuTrigger1"
leftClicktoOpen="true" style="display:none">
<div dojoType="dijit.MenuItem" class="first">Item One</div>
<div dojoType="dijit.MenuItem">Item Two</div>
<div dojoType="dijit.MenuItem">Item Three</div>
<div dojoType="dijit.MenuItem">Item Four is really, really long item.</div>
</div>
and this:
// Tools Menu
// trigger
<div id="toolsButton">Tools</div>
// menu
<div dojoType="dijit.Menu" class="toolsMenu"
targetNodeIds="toolsButton"
leftClicktoOpen="true" style="display:none">
<div dojoType="dijit.MenuItem" class="first">Item One</div>
<div dojoType="dijit.MenuItem">Item Two</div>
<div dojoType="dijit.MenuItem">Item Three</div>
<div dojoType="dijit.MenuItem">Item Four</div>
</div>
Right now, when the menu opens, it appears under the mouse. I want it to appear in a specific position relative to the trigger*. I found the startup and onOpen events and tried writing a function that sets the style of the menu's domNode in there, but they didn't seem to take effect.
Also, I didn't see a way of finding out which node was the trigger in the context case where there are multiple ones.
I saw this & this, but wasn't able to get much further with 'em.
* FWIW, I want them positioned so that the top-left corner of the menu is aligned with the top-right corner of the context triggers, and with the bottom-left corner of the Tools menu.
I found the following css override works nicely, if you just want a relative difference in the automated positioning:
.dijitMenuPopup {
margin-left: -25px !important;
margin-top: 15px !important;
}
It turns out that dojo.popup.open (which I guess Menu inherits from) has a parameter (orient) that you can use to orient a menu relative to a node. I wound up defining a custom trigger class that knows how to take advantage of that. (I also created sub-classes for other menu-types that have different orientations, but I'll leave those out for clarity's sake.)
UPDATE: according to this page, the variable substitution method I was using in the templateString isn't recommended. Instead, you're supposed to create an attributeMap, which I've done below.
http://docs.dojocampus.org/quickstart/writingWidgets
// Define a basic MenuTrigger
dojo.declare("my.MenuTrigger", [dijit._Widget, dijit._Templated], {
// summary:
// A button that shows a popup.
// Supply label and popup as parameter when instantiating this widget.
label: null,
orient: {'BL': 'TL', 'BR': 'TR'}, // see http://api.dojotoolkit.org/jsdoc/1.3.2/dijit.popup.__OpenArgs (orient)
templateString: "<a href='#' class='button enabled' dojoAttachEvent='onclick: openPopup' onClick='return false;' ><span dojoAttachPoint='labelNode'></span></a>",
disabled: false,
attributeMap: {
label: {
node: "labelNode",
type: "innerHTML"
}
},
openPopup: function(){
if (this.disabled) return;
var self = this;
dijit.popup.open({
popup: this.popup,
parent: this,
around: this.domNode,
orient: this.orient,
onCancel: function(){
console.log(self.id + ": cancel of child");
},
onExecute: function(){
console.log(self.id + ": execute of child");
dijit.popup.close(self.popup);
self.open = false;
}
});
this.open = true;
},
closePopup: function(){
if(this.open){
console.log(this.id + ": close popup due to blur");
dijit.popup.close(this.popup);
this.open = false;
}
},
toggleDisabled: function() {
this.disabled = !this.disabled
dojo.toggleClass(this.domNode, 'buttonDisabled');
dojo.toggleClass(this.domNode, 'enabled');
dojo.attr(this.domNode, 'disabled', this.disabled);
},
_onBlur: function(){
// summary:
// This is called from focus manager and when we get the signal we
// need to close the drop down
// (note: I don't fully understand where this comes from
// I couldn't find docs. Got the code from this example:
// http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/_base/test_popup.html
this.closePopup();
}
});
// create some menus & triggers and put them on the page
dojo.addOnLoad(function(){
// MENU
cMenu = new dijit.Menu();
cMenu.addChild(new dijit.MenuItem({ label: "First Item" }));
cMenu.addChild(new dijit.MenuItem({ label: "Second Item" }));
cMenu.addChild(new dijit.MenuItem({ label: "Third Item" }));
cMenu.addChild(new dijit.MenuItem({ label: "Fourth Item is truly a really, really, really long item" }));
// TRIGGER
cTrigger = new my.MenuTrigger({
id: "cTrigger",
popup: cMenu
}).placeAt(dojo.body());
cTrigger = new my.MenuTrigger({
id: "cTrigger2",
popup: cMenu
}).placeAt(dojo.byId('contextTriggerContainer2'));
});
As I can see from dijit.Menu source code the feature you want isn't supported out of box.
What I can think of is declaring a new widget inheriting from dijit.Menu and override bindDomNode method. It binds _openMyself handler to onClick event like this:
dojo.connect(cn, (this.leftClickToOpen)?"onclick":"oncontextmenu", this, "_openMyself")
_openMyself handler takes coords from the event object that comes in as an argument.
So the idea is to pass a fabricated event object with the desired coords.
dojo.connect(cn, (this.leftClickToOpen)?"onclick":"oncontextmenu", this, function(){
var e = { target: desiredTarget, pageX: desiredX, pageY: desiredY };
this._openMyself(e);
});