Buttons are not responding to clicks in Ionic - javascript

I have the following button positioned absolutely over a canvas element:
<button class="left">Left</button>
This is the JavaScript that is supposed to respond to button click:
$(".left").mousedown(function() {
leftTimer = setTimeout(moveLeft, 10);
}).mouseup(function() {
clearTimeout(leftTimer);
});
var leftTimer,
moveLeft = function() {
if (circleX > 0) {
circleX -= 4;
}
$("h1.title").text('Clicked Left');
leftTimer = setTimeout(moveLeft, 10);
};
I added the title line to check if there was a delay. When I click the button normally, nothing happens the title does not change. I have to keep the button pressed for some time to change the text to "Clicked Left" or to move my target element. Even then there is a considerable delay between the time I first touch the button and the time the text changes. Why is that ? Let me know if I need to provide more information.

You should actually have Angular with your Ionic app, and use the ng-click element on the div you want to handle.
According to the documentation, AngularJS is required :
Ionic currently requires AngularJS in order to work at its full potential. While you can still use the CSS portion of the framework, you'll miss out on powerful UI interactions, gestures, animations, and other things.
Here is a JSBin, to make you a basic binding between your HTML and your AngularJS : https://jsbin.com/rifigakube/edit?html,js,output
If you are new to this technology here is a list to get started with AngularJS (it's pretty easy to learn if you know Javascript) :
https://angularjs.org/
https://docs.angularjs.org/tutorial/step_00
http://www.w3schools.com/angular/
https://thinkster.io/a-better-way-to-learn-angularjs
https://egghead.io/technologies/angularjs
And finally, when you think you're confident enough with AngularJS : https://scotch.io/tutorials/create-your-first-mobile-app-with-angularjs-and-ionic
(I really suggest you learn AngularJS before doing the last one, or you will get stuck after)
Hope this helps.

Related

JavaScript Help regarding adjusting/delaying Function timings

First and foremost, everything I say is only applicable for mobile version of my website - https://wtstest1.weebly.com so while troubleshooting please use the mobile view.
Secondly I have included the particular JavaScript ( Jquery ) codes relevant to the subject for your reference:
jQuery(window).load(function(){
var wW = $(window).width();
$(document).off('click','.wsite-menu-item');
$(document).on('click','.wsite-menu-item', function(){
var _this = $(this);
var _href = _this.attr('href');
var _top;
if(wW > 992){
_top = $(_href).offset().top - 64;
$('body').removeClass('nav-open')
}else{
_top = $(_href).offset().top - 50;
$('body').removeClass('nav-open')
$('.boo_onepage').removeClass('show')
}
$('html,body').stop().animate({scrollTop:_top},500)
})
When you will load my website in mobile view, you will find a arrow at top having some options, tapping on each of them scrolls to particular sections within my webpage.
Although the arrow didn't minimized on its own after an option was tapped which was inconvenient hence I added the second last line you can see in code:
$('.boo_onepage').removeClass('show')
Now adding this line made the arrow to minimize on its own when a option was chosen
But it lead to another issue - my main reason of posting this.........
Now The arrow minimizes on its own after chosing an option but it happens way too quickly and in the process it skips the active-tab/hover effect which was there originally.
It helped to let the user know where they have tapped by displaying the tab in yellow color for like close to less than 1 second then proceeded to scroll to requested section.
Can someone adjust the jQuery code to make the arrow minimize on its own after choosing an option and still retaining the active tab/hover effect.
What I tried from my end - I tried using setTimeout(function() to delay function - $('.boo_onepage').removeClass('show') by 1 second but it didn't work as well as expected.
( In case someone wants to see how adding that line made the arrow to minimize on its own but removed the hover/active option effect, you can check it here - https://wtstest.weebly.com )
I had read your post...!
You can follow my code below
// When click arrow navbar it's increase size follow 1s
$(document).on('click','.boo_onepage_toggle', function(){
$('.boo_onepage_menu').css({'font-size':'20px','transition':'1s'})
})
// When choose one option the arrow will decrease size follow 1s
// The user when navigation to arrow It's screen point similar button for user understand "Click"
$(document).on('click','.wsite-menu-item', function(){
$('.boo_onepage_menu').css({'font-size':'10px','cursor':'pointer','transition':'1s'})
$('.boo_onepage').removeClass('show')
})
// Hover when user move to arrow
$('.boo_onepage_menu').mouseover(function(){
$(this).css({'font-size':'20px','cursor':'pointer','transition':'1s'})
}).mouseout(function() {
$(this).css({'font-size':'10px','cursor':'pointer','transition':'1s'})
})
Have a nice day...!

Different Approach to Hiding image in Javascript

I'm responsible for developing an approach/algorithm to hide image on the trigger. But hiding should be in such a way that it would be hard for developers to do "inspect code" and change certain javascript variables or setting some condition true. So visibility:hidden is a no for sure because it's easy to get rid of it through "inspect code".
Only viable option I can think of is injecting image code () through JQuery which would make it quite work for someone to trigger it manually (I believe). But not sure if it's good enough.
What kind of an approach I can implement? Every opinion counts. Thank you.
To clarify: there are 2 images. each button hover will trigger visibility of one of the images. And the goal is to forbid the user from viewing both of them simultaneously. And they may avoid this by changing script conditions and variables. How to prevent that happening?
You could use something like the below to detect when someone uses inspect element to completely hide the content they're trying to change.
var currentHtmlContent;
var element = new Image();
var elementWithHiddenContent = document.querySelector("#element-to-hide");
var innerHtml = elementWithHiddenContent.innerHTML;
element.__defineGetter__("id", function() {
currentHtmlContent= "";
});
setInterval(function() {
currentHtmlContent= innerHtml;
console.log(element);
console.clear();
elementWithHiddenContent.innerHTML = currentHtmlContent;
}, 1000);
It will then show the content when they stop inspecting.

Set ng-disabled parameter to button in $ionicPopup

I'm trying to create a $ionicPopup where one of the buttons is disabled under certain conditions (being the return value of a function, let's call it MyFunction()). I want to use ng-disabled for this purpose.
The problem is, I don't know how to programmatically add the attribute "ng-disabled".
What I tried so far:
Adding the attribute when creating the popup, like attr:"ng-disabled='myFunction()'"
Adding the attribute after the popup was created, using JavaScript => The problem is that the setAttribute() method is executed before the popup is actually shown, so I would need a way to detect when the popup is open, and execute the method only then.
Creating the button as html elements inside the popup template, and not setting any button with the $ionicPopup.show() method. This works, but I'm not satisfied with it because I don't want to "reinvent the wheel" and redefine CSS styles for buttons that are already covered by Ionic framework.
My JS function:
$scope.displayPopUp=function(){
var alertPopup = $ionicPopup.show({
templateUrl: 'sharePopUp.html',
title: 'Invite a friend',
cssClass: 'popupShare',
buttons:[
{
text:'Close',
type: 'button-round button-no',
onTap: function(){
/* Some instructions here */
}
},
{ /* v THIS IS THE BUTTON I WANT TO DISABLE UNDER CERTAIN CONDITIONS v */
text:'Share',
type: 'button-round button-yes',
onTap: function(){
/* Some instructions here */
}
}
]
});
$(".button-yes")[0].setAttribute("ng-disabled", "MyFunction()"); /* NOT WORKING BECAUSE button-yes IS NOT EXISTING YET */
}
TL;DR
$timeout(function () { // wait 'till the button exists
const elem = $('.button-yes')[0];
elem.setAttribute('ng-disabled', 'MyFunction()'); // set the attribute
$compile(elem)(angular.element(elem).scope()); // Angular-ify the new attribute
});
Live demo: working plunk
Introduction
That problem you're encountering, it's a real one, and it has apparently been for years.
Here's the latest version of the code used by $ionicPopup (last updated in December 2015)
This template is the one used by your Ionic-1 popups (from the first lines of the code linked above):
var POPUP_TPL =
'<div class="popup-container" ng-class="cssClass">' +
'<div class="popup">' +
'<div class="popup-head">' +
'<h3 class="popup-title" ng-bind-html="title"></h3>' +
'<h5 class="popup-sub-title" ng-bind-html="subTitle" ng-if="subTitle"></h5>' +
'</div>' +
'<div class="popup-body">' +
'</div>' +
'<div class="popup-buttons" ng-show="buttons.length">' +
'<button ng-repeat="button in buttons" ng-click="$buttonTapped(button, $event)" class="button" ng-class="button.type || \'button-default\'" ng-bind-html="button.text"></button>' +
'</div>' +
'</div>' +
'</div>';
There's one line in particular that's interesting to us: the button template:
<button ng-repeat="button in buttons" ng-click="$buttonTapped(button, $event)" class="button" ng-class="button.type || \'button-default\'" ng-bind-html="button.text"></button>
As you can see, there's just no built-in way to alter its button's attributes.
Two approaches
From here, you've got two fixes:
We can contribute to their project on GitHub, implement the missing functionality, write the tests for it, document it, submit an issue, a Pull Request, ask for a newer version to be released and use the newer version.
This is the ideal solution, 'cause it fixes everyone's problems forever. Although, it does take some time. Maybe I'll do it. Feel free to do it yourself though, and tag me, I'll +1 your PR 👍
Write a dirty piece of code that monkey-patches your specific problem in your specific case
This isn't ideal, but it can be working right now.
I will explore and expand on the (quick 'n dirty) option #2 below.
The fix
Of the 3 things you've tried so far:
the first one is simply not a thing (although it could be if we implement it, test it, document it and release it)
the third one is rather unmaintainable (as you know)
That leaves us with the second thing you mentioned:
Adding the attribute after the popup was created, using JavaScript
The problem is that the setAttribute() method is executed before the popup is actually shown, so I would need a way to detect when the popup is open, and execute the method only then.
You're right, but that's only part one of a two-fold problem.
Part 1: The button isn't created yet
Actually, you can delay that call to setAttribute to later, when the popup is shown. You wouldn't wanna delay it by any longer than would be noticeable by a human, so you can't reasonably go for anything longer than 20ms.
Would there be some callback when the popup is ready, we could use that, but there isn't.
Anyways, I'm just teasing you: JavaScript's "multi-tasking" comes into play here and you can delay it by 0 millisecond! 😎
In essence, it has to do with the way JS queues what it has to do. Delaying the execution of a piece of code by 0ms puts it at the end of the queue of things to be done "right away".
Just use:
setTimeout(function () {
$(".button-yes")[0].setAttribute("ng-disabled", "MyFunction()");
}, 0); // <-- 0, that's right
And you're all set!
Well, you do have a button whose ng-disabled attribute indeed is "MyFunction()". But it's not doing anything...
So far, you simply have an HTML element with an attribute that doesn't do anything for a simple HTML button: Angular hasn't sunk its teeth into your new DOM and hooked itself in there.
Part 2: Angular isn't aware of the new attribute
There's a lot to read here about this, but it boils down to the following: Angular needs to compile your DOM elements so that it sets things in motion according to your Angular-specific attributes.
Angular simply hasn't been made aware that there's a new attribute to your button, or that it should even concern itself with it.
To tell Angular to re-compile your component, you use the (conveniently named) $compile service.
It will need the element to compile, as well as an Angular $scope to compile it against (for instance, MyFunction probably doesn't exist in your $rootScope).
Use it once, like so:
$compile(/* the button */ elem)(/* the scope */ scope);
Assuming the following element is your button:
const elem = $(".button-yes")[0];
... you get its actual scope through its corresponding Angular-decorated element thingy:
const scope = angular.element(elem).scope();
So, basically:
const elem = $('.button-yes')[0];
elem.setAttribute('ng-disabled', 'MyFunction()');
$compile(elem)(angular.element(elem).scope());
Tadaaa! That's it! 🎉
... sort of. Until there's some user interaction that would alter the corresponding $scope, the button is actually not even displayed.
Bonus Part: Avoid $scope.$apply() or $scope.$digest()
Angular isn't actually magically picking up things changing and bubbling it all to the right places. Sometimes, it needs to explicitly be told to have a look around and see if the elements are in sync with their $scope.
Well, more specifically, any change that happens asynchronously won't be picked up by itself: typically, I'm talking about AJAX calls and setTimeout-delayed functions. The methods that are used to tell Angular to synchronise scopes and elements are $scope.$apply and $scope.$digest... and we should thrive on avoiding them :)
Again, there's lots of reading out there about that. In the meantime, there's an Angular service (again), that can (conceptually, it's not the literal implementation) wrap all your asynchronous code into a $scope.$apply() -- I'm talking about $timeout.
Use $timeout instead of setTimeout when you will change things that should alter your DOM!
Summing it all up:
$timeout(function () { // wait 'till the button exists
const elem = $('.button-yes')[0];
elem.setAttribute('ng-disabled', 'MyFunction()'); // set the attribute
$compile(elem)(angular.element(elem).scope()); // Angular-ify the new attribute
});
Live demo: working plunk
I think in ionic v1 Ionic Framework team have not implemented this yet as per (Oct 6, '14 10:49 PM). I think still situation is same. But there is a work around for that.
Option 1:
What I understand from your question, your main purpose is to prevent user to click on buttonDelete ionicPopup buttons and perform some instructions until MyFunction() returns truecreate your own template with buttons which you can fully control them. Below is code:
You can achieve this inside onTap :. Here you can add condition of your MyFunction() like below:
JavaScript:
// Triggered on a button click, or some other target
$scope.showPopup = function() {
// Enable/disable text"Share" button based on the condition
$scope.MyFunction = function() {
return true;
};
//custom popup
var myPopup = $ionicPopup.show({
templateUrl: 'Share'"popup-template.html",
typetitle: 'button-round"Invite button-yes'a friend",
onTapscope: function(e)$scope
{ });
// close popup on Cancel ifbutton (MyFunctionclick
$scope.closePopup = function()) {
myPopup.close();
};
};
HTML:
/*<button Someclass="button instructionsbutton-dark" hereng-click="showPopup()">
*/ show
</button>
}<script elseid="popup-template.html" {type="text/ng-template">
<p>Share button is disabled if condition not /satisfied</don'tp>
allow the user to<button performclass="button unlessbutton-dark" MyFunctionng-click="closePopup()"> returns
true Cancel
</button>
e.preventDefault<button class="button button-dark" ng-disabled="MyFunction(); == true">
}Share
}</button>
}</script>
Working example here Here is working codepen snippet:
https://codepen.io/anon/pen/bvXXKG?editors=1011
Option 2:
Delete ionicPopup buttons and create your own template with buttons which you can fully control them. Below is code:
JavaScript:
// Triggered on a button click, or some other target
$scope.showPopup = function() {
// Enable/disable "Share" button based on the condition
$scope.MyFunction = function() {
return true;
};
//custom popup
var myPopup = $ionicPopup.show({
templateUrl: "popup-template.html",
title: "Invite a friend",
scope: $scope
});
// close popup on Cancel button click
$scope.closePopup = function() {
myPopup.close();
};
};
HTML:
<button class="button button-dark" ng-click="showPopup()">
show
</button>
<script id="popup-template.html" type="text/ng-template">
<p>Share button is disabled if condition not satisfied</p>
<button class="button button-dark" ng-click="closePopup()">
Close
</button>
<button class="button button-dark" ng-disabled="MyFunction() == true">
Share
</button>
</script>
Here is working codepen snippet:
https://codepen.io/anon/pen/qYEWmY?editors=1010
Note: Apply your own styles/button's alignment etc
I hope it will help you.

IntersectionObserver blur element on unfocus

Recently I have been working on a project with an image grid for a friend of mine. The idea behind the website was that when the images in one row come into focus it pops out and the remaining go back into their original sizes.
After some research I found the IntersectionObserver API for JavaScript and the following example: http://codepen.io/pawelgrzybek/pen/YWqWXJ I modified the code to change the threshold to
let options = {
threshold: [1.0]
};
but those are just personal modifications, the issue I had was when I scroll down to the next element that comes into focus using the visible class but the previous elements still stay in focus. I wasn't sure about the best way to go about doing this.
I found examples and was able to notice the following code:
function updateStatus(visiblity) {
console.log(visiblity);
const status = document.querySelector('.status');
status.textContent = visiblity;
status.className = 'status status--' + visiblity;
}
but this is only for the top bar in the Simple Example I needed some help figuring this out, please and thank you everyone!

Touchswipe.js not allowing select box to open on desktop

I cant get my select box to work with i enable touchenabled in desktops. Viewing my fiddles you will see when you click on "ARTICLE" the select box will only work if i disable touchenabled for desktop users.
touchenabled:"on" http://jsfiddle.net/y82XD/ (ARTICLE select box will not work)
touchenabled:"off" http://jsfiddle.net/y82XD/3/ (ARTICLE select box works fine)
I am using a script to detect mobile devices and want to enable touchenabled: "on" , when device.mobile is detected. The mobile detection script has a JavaScript Method called device.mobile() that can be used . So using the below script for the slider , how would i go about incorporating the device.mobile() to set touchenabled:"on" for mobile , while setting touchenabled:"off" for everything else ?
var tpj=jQuery;
tpj.noConflict();
tpj(document).ready(function() {
if (tpj.fn.cssOriginal!=undefined)
tpj.fn.css = tpj.fn.cssOriginal;
tpj('#slidebox').services(
{
width:620,
height:460,
slideAmount:4,
slideSpacing:10,
touchenabled:"off",
NEED CODE HERE to enable touchenabled:"on" when device.mobile detected
mouseWheel:"off",
hoverAlpha:"on",
slideshow:3500,
hovereffect:"on",
callBack:function() { }
});
});
I was able to get the select box to function by changing the following two options in your slidebox services:
touchenabled:"off"
hoverAlpha:"off"
Those were previously on. When I turned them off, the parent slidebox div lost its mousedown and touchcancel event listeners.
I don't know enough about this package to understand what implications this might have. But it looked to be doing everything it was doing previously.
If you need to have these options on, then perhaps you could turn them off when this particular page is displayed? Or maybe you could unbind the two listeners that are causing the problems when the page is displayed.
UPDATE:
Ok, after reading your new comments, I'm not sure why this won't work, but it does seem a bit simple, so maybe I still don't understand it 100%.
var touchEnabledValue = (device.mobile) ? "on" : "off;
tpj('#slidebox').services(
{
width:620,
height:460,
slideAmount:4,
slideSpacing:10,
touchenabled: touchEnabledValue,
mouseWheel:"off",
hoverAlpha: touchEnabledValue,
slideshow:3500,
hovereffect:"on",
callBack:function() { }
}

Categories