Ionic4 sliding item problems - ionic4

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>

Related

Vue binding is sometimes putting "\" \"" around the strings, but v-html makes it always say Object object?

I am trying to make a quiz game and after getting the answers to shuffle around, they sometimes are surrounded by "\" \"" marks. When just displaying the correct answer, it will not have these marks. I have tried using v-html which normally gets rid of this issue, however then all the answers are [Object object]. I have tried trying to retrieve just part of the arrays and objects with [0] [2] and so one but that didn't work either.
Here is my html:
Style binded so that if that button is selected, the background colour of the button will change. Colour is a variable changed when answer is checked -->
<button class="answer" :disabled="answered" #click="checkAnswer(shuffled[0])" :style="selected == shuffled[0].value && {backgroundColor: colour}">{{shuffled[0]}}</button>
<button class="answer" :disabled="answered" #click="checkAnswer(shuffled[1])" :style="selected == shuffled[1].value && {backgroundColor: colour}">{{shuffled[1]}}</button>
<button class="answer" :disabled="answered" #click="checkAnswer(shuffled[2])" :style="selected == shuffled[2].value && {backgroundColor: colour}">{{shuffled[2]}}</button>
<button class="answer" :disabled="answered" #click="checkAnswer(shuffled[3])" :style="selected == shuffled[3].value && {backgroundColor: colour}">{{shuffled[3]}}</button>
<!-- Button running function to end game with parameters of current correctCount and totalQuestions -->
<button type="button" #click="finish(correctCount, totalQuestions)" class="btn button done">Finish</button> <div class="correct"><p v-if="answered"><strong>Correct Answer:</strong> {{correctAnswer}}</p></div><button type="button" :disabled="!nextAvailable" #click="getQ(selectedDifficulty)" #click="shuffle(options)" class="btn button next">Next</button>
<!-- Button which is disabled when a question loads and runs functions to shuffle the answers and get a new question -->
</div>
<h3>Debugging</h3>
<p><strong>Correct Answer: </strong>{{correctAnswer}}</p>
</div>
And here is my relevant JS:
let getQ = async function() {
let response = await fetchURL('https://the-trivia-api.com/api/questions?categories=film_and_tv&limit=1&region=AU'); // api source link
this.correctAnswer = response[0].correctAnswer;
this.incorrectAnswerOne = response[0].incorrectAnswers[0];
this.incorrectAnswerTwo = response[0].incorrectAnswers[1];
this.incorrectAnswerThree = response[0].incorrectAnswers[2];
this.question = response[0].question;
this.shuffle(options); // shuffles the answers in options variable
this.answered = false; // resets the disabled buttons
this.nextAvailable = false; // disables 'next' button
this.totalQuestions++; // increases number of total questions
}
// function to shuffle the answers
let shuffle = function(array) {
this.selected = null; // resets selected variable
let num = array.length, t, raInt;
// while there are remaining elements to shuffle
while (num) {
// choose random
raInt = Math.floor(Math.random() * num--);
// swap with current element
t = array[num]
array[num] = array[raInt];
array[raInt] = t;
}
this.shuffled = array.value; // saves to shuffled variable
}
All variables are declared and returned in the component. What I want is for it to always have every answer shuffled and without these markings.
There are some error messages but I am not quite sure what they mean:
If I haven't provided enough information or code, please feel free to say if you need more.

Problem using click event in angular 8 directive

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;
}

Interactive nodes in vis js network

When node is selected I want to add a icon on node and on icon click I want to give options to edit or deleted selected node. Is this possible or how to implement this in Vis js?
you can use the click event or nodeSelected.
like this:
network.on('click', function (properties) {
selection = properties.nodes
if (selection > 0) {
var node_sel = nodes.get([selection])[0];
if(node_sel['selected']){
alert('add you buttons');
}
else{
alert('change the style here');
node_sel['selected'] = true;
node_sel['shape'] = 'box';
nodes.update(node_sel);
var msg = JSON.stringify(nodes.get([selection]))
alert(msg);
}
}
});
see this plunker, instead of the alerts put your code.

How to add background-color to text navigation on image slider?

I have an image slider that is controlled by text navigation. The text is highlighted orange when it's relative slide is current in the gallery. I would like the other text to have an inactive state with a black background but cannot get this to work!
(In case that didn't make much sense! Basically, I want background-color orange when current, background-color black when inactive.) THANKS
$(document).ready(function(){
$('.slider').each(function(e){
if(e == 0){
$(this).addClass('current');
}
$(this).attr('id', 'handle' + e);
})
$('.tabs li').each(function(e){
if(e == 0){
$(this).addClass('current'); //adds class current to 1st li
}
$(this).wrapInner('<a class="title"></a>'); //wraps list items in anchor tag
$(this).children('a').attr('href', '#handle' + e);//adds href to the anchors
t = $(this).children('a').text();
$('#handle' + e).append('<h2>' + t + '</h2>'); //adds h2 and text to big images
})
$('.tabs li a').click(function(){
c = $(this).attr('href');
if($(c).hasClass('current')){
return false;
}else{
showImage($(c), 20);
$('.tabs li').removeClass('current');
$(this).parent().addClass('current');
return false;
}
})
runRotateImages();
$("#featured").hover(
function(){
clearTimeout(xx);
},
function(){
runRotateImages();
}
)
})
function showImage(img, duration){
$('.slider').removeClass('current').css({
"opacity" : 0.0,
"zIndex" : 2
});
img.animate({opacity:1.0}, duration, function(){
$(this).addClass('current').css({zIndex:1});
});
}
function rotateImages(){
var curPhoto = $("div.current");
var nxtPhoto = curPhoto.next();
var curTab = $(".tabs li.current");
var nxtTab = curTab.next();
if (nxtPhoto.length == 0) {
nxtPhoto = $('#featured div:first');
nxtTab = $('.tabs li:first-child');
}
curTab.removeClass('current');
nxtTab.addClass('current');
showImage(nxtPhoto, 300);
}
function runRotateImages(){
xx = setInterval("rotateImages()", 5000);
}
I have added a jsfiddle - http://jsfiddle.net/n5EPM/3/
However, on jsfiddle it does not seem to automatically cycle through the images, not sure why, have no problems in browser.
Try using not() method: http://api.jquery.com/not/
Basically, you need to create a new class disabled
.disabled{
background-color:#000000;
}
Then, add the following line to your tabs.li's each loop:
$(".tabs li").not(".current").addClass('disabled'); //add disabled class for non-current tabs
At last you need to remove disabled class in the rotateimage() function before assigning current and then disable non-current again. like this:
curTab.removeClass('current');
nxtTab.removeClass('disabled'); //remove diabled class
nxtTab.addClass('current');
$(".tabs li").not(".current").addClass('disabled'); // disable non-current again
Working jsfiddle here: http://jsfiddle.net/n5EPM/9/
This might not be the perfect solution but you will need to tweak it a little bit.
Hope this helps.

Cycle Jquery UI Tab on "previous" and "next" button

I am using Jquery UI Tabs for my website.
<script type='text/javascript'>
//<![CDATA[
jQuery(window).load(function(){
jQuery('#myTabs').tabs({ fx: { opacity: 'toggle' }});
jQuery('.next-product').click(function(){
var jQuerytabs = jQuery('#myTabs').tabs();
var selected = jQuerytabs.tabs('option', 'selected');
jQuerytabs.tabs('select', selected+1);
});
jQuery('.previous-product').click(function(){
var jQuerytabs = jQuery('#myTabs').tabs();
var selected = jQuerytabs.tabs('option', 'selected');
jQuerytabs.tabs('select', selected-1);
});
As you can see that i have been using the previous next button to move from one tab to another.
My question is "When i click on next and if the last tab is open then automatically the first tab should get open, and similarly When i click on previous and if the first tab is open then automatically the last tab should get open"
Please help me out, i am stuck from over 3 days now and no solution. I have searched a lot on net but no solution for this.
You can count the number of .ui-tabs-panel elements.
jQuery(window).load(function() {
var $tabs = jQuery('#myTabs');
$tabs.tabs({
fx: {
opacity: 'toggle'
}
});
var amount = $tabs.find('.ui-tabs-panel').length;
jQuery('.next-product').click(function() {
var selected = $tabs.tabs('option', 'selected');
$tabs.tabs('select', selected + 1 === amount ? 0 : selected + 1);
});
jQuery('.previous-product').click(function() {
var selected = $tabs.tabs('option', 'selected');
$tabs.tabs('select', selected === 0 ? amount - 1 : selected - 1);
});
});
DEMO
Notes:
select your tab element already and re-use the selector var $tabs = jQuery('#myTabs');, it'll be more efficient
no need to re-call .tabs() on your click handlers