Problem using click event in angular 8 directive - angular8

Im new to Angular and I have a directive that displays a dicom image and use cornerstone tools (Zoom and length) using cornerstoneJs librarie. The image is diplayed but the problem is when I want to associate each tool to two input radio so that the user can select and choose which tool to use. To do this, I created 2 functions each one activates one cornerstone tools which I associated to each input radio, but the problem is that only the first function is executed when I click on the two input radio.
cornerstone.directive.ts :
#Output() myClick1: EventEmitter<any> = new EventEmitter();
#Output() myClick2: EventEmitter<any> = new EventEmitter();
#HostListener('click', ['$event'])
onClick1(event) {
cornerstoneTools.addTool(cornerstoneTools[`${'Length'}Tool`]);
cornerstoneTools.setToolActive('Length', { mouseButtonMask: 1 } );
this.myClick1;
}
#HostListener('click', ['$event'])
onClick2(event) {
cornerstoneTools.addTool(cornerstoneTools[`${'Zoom'}Tool`]);
cornerstoneTools.setToolActive('Zoom', { mouseButtonMask: 1 } );
this.myClick2;
}
viewer.html :
<input type="radio" class="left" name="tool" (myClick1)="onClick1($event)" appCornerstone> Length
<input type="radio" class="left" name="tool" (myClick2)="onClick2($event))" appCornerstone> Zoom
The problem is when I select length tool it is enabled, but when I select zoom the length tool sill enabled and the zoom tool is not activated.
Thank u so much !

Take a look at this issue https://github.com/cornerstonejs/cornerstoneTools/issues/1018. I didn't try it but I think this will work for you.
#Output() myClick1: EventEmitter<any> = new EventEmitter();
#Output() myClick2: EventEmitter<any> = new EventEmitter();
#HostListener('click', ['$event'])
onClick1(event) {
cornerstoneTools.addTool(cornerstoneTools[`${'Length'}Tool`]);
cornerstoneTools.setToolActive('Length', { mouseButtonMask: 1 } );
cornerstoneTools.setToolDisabled('Zoom');
this.myClick1;
}
#HostListener('click', ['$event'])
onClick2(event) {
cornerstoneTools.addTool(cornerstoneTools[`${'Zoom'}Tool`]);
cornerstoneTools.setToolActive('Zoom', { mouseButtonMask: 1 } );
cornerstoneTools.setToolDisabled('Length');
this.myClick2;
}

Related

vue element checkbox not working in edit mode

I am using checkbox given by vue-element, visit https://element.eleme.io/#/en-US/component/checkbox.
But in edit mode they are not able to select anymore.
Please help me out.
<el-checkbox-group v-model="form.activity_type" size="small">
<el-checkbox-button
v-for="(all_type,index) in all_activity"
:key="index"
:label="all_type.id"
>{{all_type.activity_type_name}}</el-checkbox-button>
</el-checkbox-group>
<el-checkbox-group v-model="form.activity_type" size="small">
<e`enter code here`l-checkbox-button
v-for="(all_type,index) in all_activity"
:key="index"
:label="all_type.id">
{{all_type.activity_type_name}}
</el-checkbox-button>
</el-checkbox-group>
Hi you in order to show checkbox in edit mode you can do it like this:
data() {
return {
form: {
activity_type: []
}
};
}
import {activityData} from "#/api/activity";
2)under method function:
activityData(id).then(response => {
this.form = response.res;
});
3) and then from your controller function you can pass data in this format:
$allData = [];
$allData['activity_type'] = array(1,3);//the ids one you want to show check
return response()->json(["res" => $allData]);

Ionic4 sliding item problems

I am building a chat messaging app with Ionic4. The expected behavior is to have a sliding item with the picture and name of a friend and upon sliding left, add and remove friend buttons are revealed to add or remove a friend from the chat. Further, if a friend is added to the chat the add button is disabled and the remove button is enabled using the [disabled] tag. Finally if any friends exist that have been added, a button on the bottom appears, to take us to the chat page and initialize a conversation.
The problem is that I initially swipe left on the bottom most friend, and then we see the add and remove buttons with add disabled, So far so good. I then click add and the remove button becomes undisabled, and the add button becomes disabled. I then click remove and it works great!
I then try the same thing on the friend above the bottom and everything fails. The buttons do not enable/disable, but when the remove button still appears disabled.
So far I have tested the custom pipe(s) I created and they have all shown true when a friend appears within chatfriends, so that condition is ok.
//chats.html
<ion-list-header>
Friends
</ion-list-header>
<ion-list>
<ion-item-sliding #slidingitem *ngFor="let key of myfriends" >
<ion-item >
<ion-avatar item-left>
<img src="{{key.photoURL}}">
</ion-avatar>
<h2>{{key.displayName}}</h2>
</ion-item>
<ion-item-options slide="left">
<button ion-button [disabled]="(chatfriends | contains:key)" color="primary" (click)="addfriendtochat(key)" >
Add
</button>
<button ion-button [disabled]="!(chatfriends | contains:key)" color="danger" (click)="removefriendfromchat(key,slidingitem)" >
Remove
</button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
//**************************
//chats.ts
ionViewWillEnter() {
//chats.ts has to listen to chatconnect node as it does with the nodes below
this.requestservice.getmyrequests();
this.requestservice.getmyfriends();
this.requestservice.getmychatconnects();
//this.contains.transform(localfriends, "Eddie");
// this.myfriends = [];
this.events.subscribe('gotrequests', () => {
this.myrequests = [];
this.myrequests = this.requestservice.userdetails;
});
this.events.subscribe('friends', () => {
this.myfriends = [];
this.myfriends = this.requestservice.myfriends;
});
this.events.subscribe('gotchatconnects', () => {
this.mychatconnects = [];
this.mychatconnects = this.requestservice.chatconnects;
});
}
ionViewDidLeave() {
this.events.unsubscribe('gotrequests');
this.events.unsubscribe('friends');
this.events.unsubscribe('gotchatconnects');
}
//this function adds a friend to the chat and a friend to the chatfriend array, and also sets the flag that determines whether or not to show the start chat button
addfriendtochat(friend){
if(this.myfriends.includes(friend)){
this.chatservice.addfriendtochat(friend);
if(this.chatservice.getfriendcount() > 0){
this.friendsinarray = true;
}else{
this.friendsinarray = false;
}
}
this.chatfriends = this.chatservice.getfriends();
}
//this function removes a friend from the chat and removes a friend from the chatfriend array, and also sets the flag that determines whether or not to show the start chat button
removefriendfromchat(friend, slidingitem: ItemSliding){
if(this.myfriends.includes(friend)){
this.chatservice.removefriendfromchat(friend);
if(this.chatservice.getfriendcount() > 0){
this.friendsinarray = true;
}else{
this.friendsinarray = false;
}
}
this.chatfriends = this.chatservice.getfriends();
slidingitem.close();
}
There is no error message, the one notable thing is that upon the steps above when it fails, the items are not reloaded.
I wasn't able to get the exact sliding action I wanted, but the problem was really in the rendering of buttons. After removing the slider the buttons did not hide and unhide or [enable/disable] the add and remove from chat buttons, exactly as previously described. As I posted before, the page did not seem to re-render after objects were updated in the providers. I believe that the problem was just that, subscribing to events from two providers. I switched the tracking of added friends to my requests.ts. This was for two reasons.
1. I pulled my list of friends, called myfriends, from my firebase rest api using that provider, so my object to track whether one of my friends friends was added to the chat, called friendobjs, were there as well. Further I had to use events from both objects to fill in info on my chats.ts page.
2. Everything else on my page that was subscribing to events from that provider so I didn' think conflicts would arise.
Here is the working code, which hides and unhides the add and remove buttons for each friend displayed.
//chats.ts
ionViewWillEnter() {
//chats.ts has to listen to chatconnect node as it does with the nodes below
this.requestservice.getmyfriends();
this.events.subscribe('friends', () => {
this.myfriends = [];
this.friendobjs = [];
this.myfriends = this.requestservice.myfriends;
this.friendobjs = this.requestservice.friendobjs;
this.singleArray = [];
for (var _i = 0; _i < this.myfriends.length; _i++) {
this.singleArray.push({
myfriends: this.myfriends[_i],
friendobjs: this.friendobjs[_i]
});
}
});
this.events.subscribe('addedfriendtochat', () => {
this.friendobjs = [];
this.friendobjs = this.requestservice.friendobjs;
this.singleArray = [];
for (var _i = 0; _i < this.myfriends.length; _i++) {
this.singleArray.push({
myfriends: this.myfriends[_i],
friendobjs: this.friendobjs[_i]
});
}
});
this.events.subscribe('removedfriendfromchat', () => {
this.friendobjs = [];
this.friendobjs = this.requestservice.friendobjs;
this.singleArray = [];
for (var _i = 0; _i < this.myfriends.length; _i++) {
this.singleArray.push({
myfriends: this.myfriends[_i],
friendobjs: this.friendobjs[_i]
});
}
}
removefriendfromchat(friendobj){
if(!friendobj.canbeadded){
this.requestservice.removefriendfromchat(friendobj);
if(!this.requestservice.canchat){
this.friendsinarray = true;
}else{
this.friendsinarray = false;
}
}
addfriendtochat(friendobj){
if(friendobj.canbeadded){
this.requestservice.addfriendtochat(friendobj);
if(!this.requestservice.canchat){
this.friendsinarray = true;
}else{
this.friendsinarray = false;
}
}
}
//chats.html
<ion-item *ngFor="let single of singleArray" >
<ion-avatar item-left>
<img src="{{single.myfriends.photoURL}}">
</ion-avatar>
<h2>{{single.myfriends.displayName}}</h2>
<h2>{{single.friendobjs.canbeadded}}</h2>
<button ion-button round item-right color="primary" [hidden]="!single.friendobjs.canbeadded" (click)="addfriendtochat(single.friendobjs)" >
<ion-icon name="checkmark"></ion-icon>
Add
</button>
<button ion-button round item-right color="danger" [hidden]="single.friendobjs.canbeadded" (click)="removefriendfromchat(single.friendobjs)" >
<ion-icon name="trash"></ion-icon>
Remove
</button>
</ion-item>

Form number input does not work with keys

<template v-for="(paint, index) in paints">
<input type="number" v-bind:min="1" v-model.number="paint.qty">
</template>
-
var paintListApp = new Vue({
delimiters: ['${', '}'],
el: '#paintListApp',
data: {
paints: paints
},
methods: {
addToSet: function(sku, name, image) {
// method triggered when item is clicked - sends data to event bus
this.$eventHub.$emit('addToSelectedPaints', sku, name, image)
}
}
});
var paintWidget = new Vue({
el: '#paintWidget',
delimiters: ['${', '}'],
data: {
paints: []
},
created() {
// data picked up - processed by 'addToSelectedPaints'
this.$eventHub.$on('addToSelectedPaints', this.addToSelectedPaints);
},
methods: {
addToSelectedPaints: function (sku, name, image) {
var skuIndex = _.findIndex(this.paints, function (o) { return o.sku === sku; });
if (skuIndex !== -1) {
this.paints[skuIndex].qty = this.paints[skuIndex].qty + 1;
} else {
this.paints.push({
sku: sku,
name: name,
image: image,
qty: 1
});
}
}
}
});
Trying to get min values to work on number inputs. The min is respected by the browser number plus / minus controls - however, when using the keyboard, the min attribute appears to be ignored. I've tried all sorts of things from adding a method triggered by keyup etc and testing the value, through to watchers.
Keyup gets messy as when deleting, it automatically added a 1... making it difficult to type numbers above 19... (eg, you backspace to enter 2, but - it inserts a 1).
I just need to get native browser input min attribute working with keyboard input.
** Edit **
<input type="number" v-model="paint.qty" #change="paint.qty = paint.qty < 1 ? 1 : paint.qty">
Sort of solves the issue, albeit at the expense of the min attribute. Hooking into the #change event. If input is less than 1, switch it for 1. It also doesn't update until the input has lost focus - not locking the ui up. So not exactly the way I wanted it to work - but the result is the same.
** edit **
I've adapted Richard Matsens answer (the accepted one) to use an input and timeout... this behaves a bit more like the Chrome and Firefox native implementation.
<input type="number" min="1" v-model.number="paint.qty" #input="handleUpdate($event, index)">
and in the handleUpdate method:
...handleUpdate(event, index) {
var updater;
clearTimeout(updater);
this.currentIndex = index;
var paints = this.paints;
var max = this.max;
updater = setTimeout(function() {
if(event.target.value < event.target.min) {
paints[index].qty = parseInt(event.target.min);
}
if(event.target.value > max){
console.log(max);
paints[index].qty = parseInt(max);
}
}, 1000);
}...
clearing the timeout to prevent the updater bit firing too many times -
bouncing / mashing etc...
From this Validate input type number with range min/max
Most browsers “ignore” (it’s their default behavior) min and max, so that the user can freely edit the input field and type a number that’s not in the range 1-5.
From this How to detect changes in nested data, can use an #input on the control and a method() to handle the check.
Works for min="0", but say min="1" may be problematic if the user wants to type in "11".
Changed to blur event to handle above caveat.
methods: {
handleUpdate(event, index) {
if(event.target.value < event.target.min) {
this.paints[index].qty = event.target.min;
}
}
},
also add #blur() to the input
<div >
<input v-for="(paint, index) in paints"
#blur="handleUpdate($event, index)"
type="number" min="2" v-model.number="paint.qty">
</div>
For completeness, you may also want to add a validation message so that the user knows why the input value is being changed.

Appcelerator Titanium dynamically populate optionDialog

I'm new to Titanium so maybe my question is a newbie one, but I'm trying to dynamically populate an option Dialog (use Alloy framework).
Is it possible to create a new ArrayCollection and pass it to my optionDialog like this :
<OptionDialog id="dialog" title="Choose Calendar" src=getAllCalendars>
<Options>
<Option id="{calendar_id}">{calendar_name}</Option>
</Options>
</OptionDialog>
Where getAllCalendar is a function that return a new Array Collection.
I know I've done things like this before in Flex but I can't make it work on Titanium so maybe it isn't the right way.
Thank you for your answers.
You need to write code in js file in Appcelerator(Alloy).
For that way you can easily get that click events.
var dialog = Ti.UI.createOptionDialog({
options : options,//Array
title : 'Hi <?'
});
dialog.show();
dialog.addEventListener('click', function(_d) {
onclickactions[_d.index];
});
I came up with this. If you opt to just create the dialog box, which works in alloy using the classic method, you can do this.
For me, the key part was to keep the order of the options with my options array. After the option was selected, you could then reference the options array with the e.index to find which was selected.
function companyDialog(){
// Build the list of options, maintaining the position of the options.
if(Alloy.Globals.Form){
Alloy.Globals.Form.Controller.destroy();
}
// My list of companies returns companyname, companycode, id
companies = db.listCompanies();
var options = [];
_.each(companies, function(val){
options.push(val.companyname + " (" + val.companycode + ")");
});
options.push("Cancel");
var dialog = Ti.UI.createOptionDialog({
title : 'Companies',
options : options
});
dialog.addEventListener('click', function(e) {
var setCode = "";
var selection = "Unknown";
if(options[e.index] != "Cancel") {
// DO WORK HERE.
alert(options[e.index].companyname);
}
});
dialog.show();
}

How do I display invalid form Dijits inside closed TitlePanes?

I have a large Dijit-based form with many Dijits in collapsible TitlePanes.
When the form validates, any invalid items hidden inside closed TitlePanes (obviously) cannot be seen. So it appears as though the form is just dead and won't submit, though, unbeknownst to the user, there's actually an error hidden in a closed TitlePane which is preventing the form processing.
What's the solution here? Is there an easy way to simply open all TitlePanes containing Dijits that are in an error state?
If validation is done by following, it will work:-
function validateForm() {
var myform = dijit.byId("myform");
myform.connectChildren();
var isValid = myform.validate();
var errorFields = dojo.query(".dijitError");
errorFields.forEach(fieldnode){
var titlePane = getParentTitlePane(fieldnode);
//write a method getParentTitlePane to find the pane to which this field belongs
if(titlePane) {
titlePane.set('open',true);
}
}
return isValid;
}
function getParentTitlePane(fieldnode) {
var titlePane;
//dijitTitlePane is the class of TitlePane widget
while(fieldnode && fieldnode.className!="dijitTitlePane") {
fieldnode= fieldnode.parentNode;
}
if(fieldnode) {
mynode = dijit.getEnclosingWidget(fieldnode);
}
return titlePane;
}
Lets say if the following is the HTML and we call the above validateForm on submit of form.
<form id="myform" data-dojo-type="dijit/form/Form" onSubmit="validateForm();">
......
</form>
Here's what I ended up doing (I'm not great with Javascript, so this might sucked, but it works -- suggestions for improvement are appreciated):
function openTitlePanes(form) {
// Iterate through the child widgets of the form
dijit.registry.findWidgets(document.getElementById(form.id)).forEach(function(item) {
// Is this a title pane?
if (item.baseClass == 'dijitTitlePane') {
// Iterate the children of this title pane
dijit.registry.findWidgets(document.getElementById(item.id)).forEach(function(child) {
// Does this child have a validator, and -- if so -- is it valid?
if (!(typeof child.isValid === 'undefined') && !child.isValid()) {
// It's not valid, make sure the title pane is open
item.set('open', true);
}
});
}
});
}