How to update onsen-ui states? - onsen-ui

I have a simple onsen-ui sample page.
It's built in Monaca (http://monaca.mobi) with Onsen UI 1.0.4.
The page contains two onsen-ui buttons (ons-button), their visibility is bound a javascript method via angular js. The buttons are mutually exclusive, meaning when button 1 is visible, button 2 must be hidden - and the other way around.
When either button is clicked, an internal flag is changed and the other button is shown.
Problem is: the visibility of the buttons is not applied correctly when the page first loads.
It only works when the user manually clicks one of the buttons.
As a counter example, there are also two normal HTML buttons on the page - these buttons work correctly as soon as the page is loaded.
Can you give me any advice? Do I have to manually force a refresh when the page is loaded?
Thank you very much in advance!
HTML code:
<div ng-controller="AppCtrl">
<strong>Click To Toggle</strong> <br>
<button ng-click="startTracking()" ng-hide="isTrackingRunning()"><strong>On</strong></button>
<button ng-click="stopTracking()" ng-show="isTrackingRunning()"><strong>Off</strong></button>
<ons-button ng-click="startTracking()" ng-hide="isTrackingRunning()">Start Tracking</ons-button>
<ons-button ng-click="stopTracking()" ng-show="isTrackingRunning()">Stop Tracking</ons-button>
</div>
JS code:
angular.module('SotraMon', ['onsen.directives'])
.controller('AppCtrl',['$scope', function($scope){
var trackingRunning = false;
$scope.isTrackingRunning = function() {
console.log("getter called, returning " + trackingRunning);
return trackingRunning;
}
$scope.startTracking = function() {
trackingRunning = true;
}
$scope.stopTracking = function() {
trackingRunning = false;
}
}]);

I can reproduce in Onsen UI 1.0.4. One solution is to use external span tag s.t.
<span ng-hide="isTrackingRunning()"><ons-button ng-click="startTracking()">Start Tracking</ons-button></span>
<span ng-show="isTrackingRunning()"><ons-button ng-click="stopTracking()">Stop Tracking</ons-button></span>

Related

Can't get CSS in AngularJS app to update instantly

I’m hoping there are some Angular 1.x experts who can show me what I’m doing wrong. I have a simple function to update which of 3 buttons in a “tab group” is the current one. This function is called whenever any of the buttons is clicked.
$scope.updateFilter = function (type, value) {
// Additional unrelated code here ...
document.getElementsByClassName('active')[0].className = document.getElementsByClassName('active')[0].className.replace(' active', '');
document.getElementById('tabButton_' + value).className += ' active';
$scope.$apply();
};
The background color of the current button is indeed highlighted but only AFTER one clicks elsewhere on the screen. In other words, it’s not updated instantly like it should.
Any ideas how to correct this?
It's hard to diagnose the issue without seeing some more code or a reproduction of your existing issue. However, from the above, you are certainly not doing the "angularjs" way. A more angular approach would be to use bindings and update the model as the user clicks different button options. A very basic (and ugly styled) example:
angular.module('myApp', [])
.controller('MainController', function () {
var self = this;
self.$onInit = function $onInit() {
// These will be ng-repeated over for the example
self.buttons = [
'Option 1',
'Option 2',
'Option 3'
];
// This is the model binding that will drive the active style
self.activeIndex = 0;
};
self.setActiveIndex = function setActiveIndex(index) {
// This is called on button click and updates the model used
// for the active button styling
self.activeIndex = index;
};
});
.active {
background: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<!-- repeat the buttons. when clicked, call controller method to update model's active index -->
<div ng-app="myApp" ng-controller="MainController as $ctrl">
<button ng-repeat="b in $ctrl.buttons" type="button" ng-class="{active: $ctrl.activeIndex===$index}" ng-click="$ctrl.setActiveIndex($index)">{{::b}}</button>
</div>
Take aways:
You probably shouldn't be doing DOM manipulation. Use existing directives and model binding, else you are losing many of the benefits you are supposed to get from angularjs.
Don't call $scope.$apply(). Angular will do this for you if you are using an ng-click in your template (which you probably should instead of building the event listeners yourself).

(angularjs ui grid)how to add an ng-click on the headercellclass?

I want an event in this name whenever I click It
I mean i'm in typescript angularjs.
I'm using angular Ui-Grid.
i want to make my header cell, clickable
is there a ways to insert an onclick event on the headercell of ui grid
I don't want to redesign the template
I just want to add click event in the headercell
Do something like this
<div ng-class="{ 'text-success': clicked, 'text-large': !clicked }">
on controller
$scope.setClass(new function(){
$scope.clicked = true;
})

Is there any way to delay ng-view?

I have layout where I have:
<li ng-click="GetLoader();">ACCOUNT</li>
<li ng-click="GetLoader();">SETTINGS</li>
On the index page, I have a menu and ng-view where I can change pages on a click
Also included on the index page is a spinner.
<div class="loading" ng-show="ticketloading" ng-init="GetLoader()">
<div>
<img class="spinner" ng-src="~/Images/ajax-loader.gif" />
</div>
</div>
In my script I have -
$scope.GetLoader = function() {
$scope.ticketloading = true;
loader.css("z-index", "1");
}
My problem is that when a user clicks on "Account" it gets loaded, but just for few milliseconds. Then it changes to all blank. I receive data from ng-view. My question is how can I delay showing ng-view to show the loader a little bit longer.
Thanx in advance!
First of all you should avoid using DOM manipulations in controller. In your case it's better to use declarative ngClass directive to set opacity.
Then your actual issue is that you don't want to use static setTimeout to hide loaded, but rather listen $routeChangeSuccess:
$rootScope.$on('$routeChangeSuccess', function() {
$rootScope.ticketloading = false;
});
and use this loading flag in template like you are currently doing.
You can put above event listener in run block for example.
You can add property in your controller, for example dataLoading and add ng-if attribute to ng-view like this:
layout
<div ng-view ng-if="!dataLoading">
controller
function loadData()
{
var self = this;
self.dataLoading = true;
dataService.loadData(params, function(){
...
self.dataLoading = false;
});
}

ng-click on firing on mobile or tablet devices

On page load i have a controller that calls a service and then binds the returned data to some $scope.objects:
app.controller("MainController", function($scope, $http, serviceGetData) {
serviceGetData.getData(function(data) {
$scope.LoginCount = data.LoginCount;
$scope.ProductInfo = data.ProductInfo;
$scope.ProfileInfo = data.ProfileInfo;
// Delayed binding
$scope.OrderHistory = { History: [] };
}
$scope.populateModel = function(model, values) {
var isArray = $.isArray(values);
$.each(values, function(key, value) {
if (isArray) {
key = this.key;
value = this.value;
}
if (model[key] !== value) {
model[key] = value;
}
});
};
}
And in my HTML, i try to bind $scope.OrderHistory by:
<h1><a href="#" ng-click="populateModel(OrderHistory , { History: OrderEntries })" >View order details</a></h1>
This is fine when viewing on laptops/desktops, but not working in tablet and mobile devices e.g. iphone/ipad
Try to add the ngTouch. From documentation:
A more powerful replacement for the default ngClick designed to be used on touchscreen devices. Most mobile browsers wait about 300ms after a tap-and-release before sending the click event. This version handles them immediately, and then prevents the following click event from propagating.
Requires the ngTouch module to be installed.
I had the same problem.
I tried adding the ngTouch library and dependency, but was still having a problem.
My static <div> elements which contained an ng-click worked fine, but the div's which were created dynamically (in an ng-repeat on the same webpage) which contained an ng-click didn't work. Tapping on them just didn't do anything.
This happened on my iPhone 6, my iPad and in Google Chrome when I asked to view my webpage on any of the device types. When I viewed the same webpage in IE or regular Chrome, all of the ng-clicks worked fine.
The solution was to use the ngMobileClick directive described here and changing my ng-click's to ng-mobile-click.
After doing that, my dynamically created click events did get triggered normally when I tapped on them on a device.
Very odd.
Had a similar issue where the ng-click inside of a ng-repeat would not trigger.
I fixed this by adding $event.stopPropagation()
Ex:
<li ng-repeat="option in $scope.options">
<span><a ng-click="trigger(); $event.stopPropagation()"></a></span>
</li>

Sencha: How to trigger click event on li element

I've been unable to figure out how to manually fire DOM events.
Here, for example, is my attempt to fire the "click" event for a li
Ext.DomQuery.select('#mapRoutesPanel ol li:nth-child('+(index+1)+')')[0].click();
It's working fine on google chrome, but when i build android native app of same application it gives me error
Uncaught TypeError: Object #<HTMLLIElement> has no method 'click'
Ext JS provides its methods for search elements in DOM tree.
Look Sencha Fiddle - its sencha touch app, i tested it on my android(opera) and iphone(safari) its work for me
Something like this:
var liElement = Ext.get('mapRoutesPanel').down('ol li:nth-child(' + (index + 1) + ')');
Have you tried
Ext.dom.Element-method-fireEvent?
Ext.DomQuery.select('#mapRoutesPanel ol li:nth-child('+(index+1)+')')[0].fireEvent('click')
Not all touch device browsers/apps support the click event because it is a mouse event. Why don't you try using Sencha's normalized event system to bind a click handler to the component, you can then check if the <li/> was clicked inside the component's click event handler.
Sencha has already done the work for us so we can handle clicks & taps in the same manner, so take advantage of it.
Btw, event delegation from a parent element is usually more performant than binding event handlers to a bunch of different DOM elements. It looks like your binding events to elements in a loop, this is a bad practice. I just wanted to point that out too.
Here is a code example:
var cmp = Ext.getCmp('someComponentId');
cmp.on('click', function(me, event) {
if (event.currentTarget.tagName == "LI") {
// do something since the <li/> tag was clicked.
// event.currentTarget will be the <li/> DOM element,
// feel free to do with it as you please :)
}
}
I did as below in my case.
Below is the sample html code of div with li s.
<div class="menu1" id="menu1">
<ul>
<li id="students_tab">Students</li>
<li id="emps_tab">Employees</li>
</ul>
</div>
And below is the extjs code to add click event to li element.
<script type="text/javascript">
Ext.onReady(function(){
var tabs= Ext.query("li", "menu1");
Ext.each(tabs, function(item){
var el = Ext.get(item);
el.on("click", function(){
var tabName = this.id.substr(0, this.id.indexOf("_"));
alert("U have clicked on "+ tabName + " tab");
});
});
});
</script>

Resources