Cytoscape.js: change layout dynamically - cytoscape.js

I want to change Cytoscape.js layout dynamically based on radio buttons.
I have:
<input type="radio" name="layout" value="preset" checked>
<input type="radio" name="layout" value="breadthfirst">
and
$("input:radio[name=layout]").click(function() {
var layout = $(this).val();
cy.layout({ name: layout });
});
The values from the buttons pass correctly, i checked them with alerts.
What am i missing?

From the document:http://js.cytoscape.org/#cy.layout,you will need to use cy.layout( options )
First, you need to call cy.layout(options) to set layout, then simply call layout.run() to make it works.
The code will be like below:
// cy here is an instance of Cytoscape
var layout = cy.layout({
name: 'random'
});
layout.run();
You can find more layouts here: http://js.cytoscape.org/#demos

Related

Change the CSS if dynamically changing image is loaded in Vue 3

I'm trying to change the CSS class of a div based on if an image is loaded. The image URL is taken from an <input> field, so <img src> can change. I've managed to set the CSS class on the first page-load using the #load event. But if I change the image's URL in the input field to a non-existent image, then the CSS doesn't change. How do I track if the input's value has changed and "re-check" if the image is loaded?
In the below example, I want to have green-bg if the image exists and red-bg if the image doesn't exist.
<div id="app">
<div :class="imgLoaded ? 'green-bg' : 'red-bg'">
<img :src=imgURL #load="imgLoaded = true" />
<br/>
<input v-model="imgURL" />
</div>
</div>
<script>
export default {
data() {
return {
imgURL: 'https://picsum.photos/200/300',
imgLoaded: false,
};
}
};
</script>
Link to CodePen
This is a nice place to use a watcher.
watch: {
imgURL(newVal, oldVal) {
if (newVal !== oldVal) this.imgLoaded = false
}
}
Hooking to the input event would work too, but there is an edge case where the new value is similar to the old value. If you then set the imgLoaded to false, the CSS class won't change to green-bg because the load event does not fire (since the url did not change).
When using a watcher you can compare the old value to the new value and only set imgLoaded to false if the values are different.
Here is the pen.
Add to you input:
<input type="text" v-model="imgURL" #input="updateURL">
and create function on methodth section:
updateURL() {
this.imgLoaded = false
}
I managed to solve my issue by using the #error method. imgLoaded would be set to false on error and set to true on load.
<div id="app">
<div :class="imgLoaded ? 'green-bg' : 'red-bg'">
<img :src=imgURL #load="imgLoaded = true" #error="imgLoaded = false" />
<br/>
<input v-model="imgURL" />
</div>
</div>
This works for the case where the CSS class is changed based on whether the image exists or not.

What is the proper way to add same component everytime a button is clicked?

I am creating a form which needs to have a button and when clicked a new component which is only an input field would be added.
For example I have only one field to put in my address, but my adress is very long so I need 2 additional input fields. I click a button twice and two more components with the input appear.
What is a proper way to achieve this functionality?
Here is a simple solution to your question.
https://jsfiddle.net/RiddhiParekh/usd57zkb/6/
Template =>
<div id="vue-instance">
<button #click="addInput">Click to add input</button>
<br>
Address:
<div v-for="i in count">
<input type="text">
</div>
</div>
Script =>
var vm = new Vue({
el: '#vue-instance',
data: {
count:1
},
methods:{
addInput(){
this.count = this.count+1
}
}
});

Compute not updating if radio is checked through code

Sorry for the title, didn't know how I could better explain it.
I have 3 radio buttons. The output should be the value of whichever radio button is selected. Except, the 3rd radio button has a textarea, and if that radio button is selected, the resulting output should be what is in the textarea. I've also linked the #click of textarea to automatically check the radio button, so if a user clicks on the textarea, that radio button gets checked automatically.
Everything works, if you see the JSFiddle code and click on the 3rd radio button and type text in the textarea, the output should work fine. But if you refresh the page, and instead of clicking the radio button, if you directly click on the textarea (which indirectly checks the radio button), writing in the textarea will not update the output. Which means the compute function is not working.
However if you click on another radio button and then click back on the 3rd radio button, things will start working fine.
Here's the code (JSFiddle here: https://jsfiddle.net/eywraw8t/43651/ )
<div id="app">
Selected option 1: {{ selectedText }}
<BR>
<input type="radio" name="item1" value="" v-model="selected[0]" /> Empty<BR>
<input type="radio" name="item1" value="Hi" v-model="selected[0]" /> Hi<BR>
<input type="radio" name="item1" value="**custom**" v-model="selected[0]" /> <textarea name="textarea0" id="textarea0" cols="30" rows="10" v-model="custom[0]" #click="customClicked"></textarea><BR>
</div>
<script>
new Vue({
el: "#app",
data: {
selected: ['', ''],
custom: ['', ''],
},
computed: {
selectedText: function() {
if (this.selected[0] != '**custom**') return this.selected[0];
return this.custom[0];
}
},
methods: {
customClicked: function(e) {
//$(e.target).prev().prop('checked', true);
this.selected[0] = '**custom**';
this.$forceUpdate();
}
}
})
</script>
You don't need jQuery for this - just bind the values to one array and use #focus event on the textarea:
new Vue({
el: "#app",
data: {
values: ['', 'Hi', ''],
selected: '',
},
computed: {
selectedText: function() {
return this.values[this.selected];
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
Selected option 1: {{ selectedText }}
<BR/>
<input type="radio" name="item1" value="0" v-model="selected" /> Empty
<BR/>
<input type="radio" name="item1" value="1" v-model="selected" /> Hi
<BR />
<input type="radio" name="item1" value="2" v-model="selected" />
<textarea name="textarea0" id="textarea0" cols="30" rows="10" v-model="values[2]" #focus="selected = '2'"></textarea>
</div>
Also the JSFiddle.
Update
As the questioner choose another answer, but i don't think that is the key point.
The reason is $forceUpdate() only force the view to re-render, not the computed properties. See the issue forceUpdate does not update computed fields
And i create a simple jsfiddle to descript it.
Raw Answer
The problem you faced is that vuejs cannot detect array change in some situation. You can see more detail in the doc vuejs list rendering
So the solution is replaced these code
this.selected[0] = '**custom**';
this.$forceUpdate();
with
this.$set(this.selected, 0, '**custom**')
While writing the answer I got an idea and it seems to work. However I still want to know if there is a "right" way of doing things which I'm missing.
The fix was to "click" the radio button instead of "checking" it:
$(e.target).prev().click();

How can we reload custom dojo widget

I've a custom dojo widget (reminder )which I want to reload on an event(on click of add button on widget a dialog will open where I'll fill reminder data and will click submit . on click of submit button widget should reload with data which I filled in dialog).
<body class="claro teller">
<form name="tellerForm">
<input type="hidden" name="expldQryStr" id="expldQryStr">
<input type="hidden" name="actionCode" id="actionCode">
</form>
<div class="row">
<div data-dojo-type="MyCashBalanceWidget.MyCashBalance" data-dojo-props="title:'Our Cash Balance Widget',data:CashBalData,data1:invtData"></div>
<div data-dojo-type="MyFrequentTasksWidget.MyFrequentTasks" data-dojo-props="pageName:'TellerLandingPage',title:'Our Some Widget',data:freqTskData"></div>
<div data-dojo-type="PendingTransactionWidget.PendingTransaction" data-dojo-props="title:'Pending Transaction Widget',data:pndTrnData,data1:pndVrfData"></div>
<div id="remWdgt" data-dojo-type="MyRemindersWidget.MyReminders" data-dojo-props="pageName:'TellerLandingPage',title:'My Reminders Widget',data:rmndrData"></div>
<div data-dojo-type="MyAppsWidget.MyApps" data-dojo-props="pageName:'TellerLandingPage',title:'My Apps Widget'"></div>
<div data-dojo-type="MyActivityWidget.MyActivity" data-dojo-props="pageName:'TellerLandingPage',title:'My Activity Widget',data:analData"></div>
</div>
<div data-dojo-type="TellerLandingPageGridWidget.TellerLandingPageGrid" data-dojo-props="title:'Teller Landing grid',data:lastTrans">
</div>
<script>
//including all the custom widgets
require(
[
"dojo/parser",
"CommonWidgets/MyFrequentTasksWidget",
"Widgets/MyCashBalanceWidget",
"Widgets/PendingTransactionWidget",
"CommonWidgets/MyRemindersWidget",
"CommonWidgets/MyAppsWidget",
"CommonWidgets/MyActivityWidget",
"Widgets/TellerLandingPageGridWidget"
],
function( parser) {
parser.parse();
});
</script>
</body>
</html>
please suggest how can I reload dojo widget .
I am not sure about your complete scenario. But in such situation, you have two ways:-
1) Add event listener to your custom widget, that will listen and modify itself
2) Recreate the widget, passing it's constructor with the new values.
Your question is quite unclear, but from the sound of it, you just want to set the innerHTML of a specific DOM node if a form within a dialog is submit. There's no reason to reload the widget for that, you could just add an event handler to the submit event of the dialog form, and use that to set the innerHTML of a specific element inside your widget.
First of all you need to add an onLoad event listener to your dialog so you know exactly when to add the event handlers to the form:
postCreate: function() {
this.myDialog = new Dialog();
this.myDialog.on("load", lang.hitch(this, this.loadDialog));
this.myDialog.set("content", "<div><form><input type='text' /><button type='submit'>Submit</button></div>");
},
This will call a function loadDialog on your widget, which could look like this:
loadDialog: function() {
var vm = this;
query("form", this.myDialog.domNode).on("submit", function(evt) {
evt.preventDefault();
vm.myLabel.innerHTML = query("input", this).val();
vm.myDialog.hide();
});
},
This function utilizes dojo/query and dojo/NodeList-manipulate to obtain the form field value when the form inside the dialog is submit. That value is then used to alter myLabel an element on the widget that I gave the attribute data-dojo-attach-point="myLabel" so that it's easily accessible from within the widget code:
templateString: "<div><label data-dojo-attach-point='myLabel'></label><button data-dojo-attach-event='onClick: openDialog'>Add</button></div>",

dojo how i can check selected tab to Boolean Type.

i'm currently create a program that i would like to add any widget selected tab. so i must know information about the selected tab. but i don't know..
how i know selected tab the information that boolean type?
for example:
if(tabs.selected==true){...}
mycode
<div id="tabContainer" data-dojo-type="dijit/layout/TabContainer"
data-dojo-props="region: 'bottom', tabPosition: 'top'"
style="height: 700px;">
<div data-dojo-type="dijit/layout/ContentPane" title="Form" id="content" class="tab" >
<h4>Example</h4>
</div>
</div>
Well, the dijit/layout/TabContainer has a property called selectedChildWidget which holds a reference to the active tab.
So, to validate if a tab is the active tab, you can do the following:
var selectedTab = registry.byId("tabContainer").get("selectedChildWidget"),
tab1 = registry.byId("content"));
if (selectedTab === tab1) {
// "content" is the selected tab
}
A full example can be found on JSFiddle: http://jsfiddle.net/tEbs9/
Maybe this one could help you.
dijit focus
You will be able to focus or track elements.
example from the dojo docs:
Try this code, it's also from the docs.
require([ "dijit/focus" ], function(focusUtil){
focusUtil.on("widget-focus", function(widget){
console.log("Focused widget", widget);
});
focusUtil.on("widget-blur", function(widget){
console.log("Blurred widget", widget);
});
});