Ionic hiding elements until scroll event - javascript

I am conditionally showing and hiding elements in my app in an accordion like fashion (can be seen in this video).
The code to perform this is:
<div class="filter-menu" ng-repeat="group in Filters | orderBy: 'title'">
<div class="filter-menu-titles" ng-click="toggleGroup(group)" ng-class="{active: isGroupShown(group)}">
<i class="icon energized" ng-class="isGroupShown(group) ? '{{group.icon}}-active' : '{{group.icon}}'"></i> <span class="filter-title-text" ng-class="{orange: isGroupShown(group)}"> {{group.title}}</span>
</div>
<div class="ion-checkbox-viewport">
<span class="filter-header" ng-show="isGroupShown(group)">{{group.title}}</span>
<br />
<ion-checkbox ng-repeat="filter in group.filters | orderBy: 'name'" class="item-accordion" value="{{filter.name}}" ng-model="filter.checked" ng-change="ModifyFilter(filter)" ng-show="isGroupShown(group)">
{{filter.name}}
</ion-checkbox>
</div>
</div>
And in the controller:
$scope.toggleGroup = function(group) {
if ($scope.isGroupShown(group)) {
$scope.shownGroup = null;
} else {
$scope.shownGroup = group;
}
};
$scope.isGroupShown = function(group) {
return $scope.shownGroup === group;
};
This works perfectly on the first load of the view. However when I navigate away from the view and then come back the elements that are shown and hidden conditionally are all hidden until a scroll event is performed. When scrolling occurs the elements are shown again.
This only occurs on iOS.

Related

Clicking through an array of NodeLists with CasperJS

I am trying to create a crawler for a project and I'm running my head up against the wall with this problem. I am trying to use CasperJS to click on the buttons on a page and return the URL that the page gets navigated to.
<product-searcher-results>
<div flex="33" flex-sm="50" flex-xs="50" layout="row" ng-repeat="product in resultsCtrl.products" class="layout-row flex-xs-50 flex-sm-50 flex-33" style="">
<md-card flex="" ng-click="resultsCtrl.goToDetail( product )" ng-class="{ 'md-whiteframe-3dp': hover }" ng-mouseenter="hover = true" ng-mouseleave="hover = false" class="fp-card fp-card-product-result mobile-padding _md flex" role="button" tabindex="0">
<img static-src="https://products.freedompop.com/kyo-c6725bk/kyo-c6725bk_C10.jpg" alt="Cheap Kyocera Hydro Vibe, 8GB Black (CDMA)" class="md-card-image" style="padding-top:10px" src="https://products.freedompop.com/kyo-c6725bk/kyo-c6725bk_C10.jpg">
<div layout="row" layout-align="end center" ng-init="condition = resultsCtrl.getCondition( product )" class="label-row layout-align-end-center layout-row">
<div ng-show="condition.isVisible" ng-class="{ grey: condition.labelColor, tiny: resultsCtrl.$mdMedia( 'xs' ) }" class="ui label ng-hide grey" aria-hidden="true">New</div>
</div>
<md-card-title>
<md-card-title-text>
<span class="md-title">Kyocera Hydro Vibe, 8GB Black (CDMA)</span>
</md-card-title-text>
</md-card-title>
<md-card-content>
<div layout="row" layout-align="end end" class="price-sizing layout-align-end-end layout-row">
<div class="msrp results-msrp">
<span class="value price-strikethrough">
$249.99
</span>
</div>
<!----><div ng-if="product.products[0].retailPrice.amount">
<div>
<span class="ui tiny statistic">
<span class="value">
$79.99
</span>
</span>
</div>
</div><!---->
</div>
</product-searcher-results>
On the home page there are a 30 buttons that I am trying to target. Below is my script for CasperJS.
casper.start("https://staging-shop.freedompop.com/product/", function( ) {
this.echo(this.getTitle( ) );
} );
casper.waitForSelector( '.md-card-image', function( ) {
console.log( 'AJAX results loaded' );
this.echo( this.getTitle( ) );
} )
casper.then( function( ) {
var buttons = document.querySelectorAll("product-searcher-results button");
while (buttons.length > 0) {
button = buttons.pop();
(function(button) {
casper.then(function() {
casper.echo("Button id is " + button);
});
casper.then(function() {
this.clickLabel('Details');
});
casper.waitForSelector('.md-card-image', function() {
casper.echo(casper.getCurrentUrl());
});
this.back();
})(button);
}
})
The last statement isn't running, i am trying to grab all the buttons from product search results. And I am trying to click on them one by one and getting the currentURL. I was able to find the first button using this statement, but I need to click on all the buttons on the page.
if( casper.exists( 'product-searcher-results button' ) ) {
this.echo( "found" )
}
this.clickLabel( 'Details' );
I am not sure how to convert the collection of nodelists to something that casper can iterate through.

Update data in view when event happens

I have an Angular app that takes a large complex data set, and allows the user to filter it down using select lists. When data is filtered, a Google Map object is updated to display associated locations with the items that have been filtered.
I am trying to work it so that when the user clicks on a map pin, the filtered list of data is updated with only the items that are associated with that location.
Some snippets of the code:
$scope.showInfoWindow = function(event, site) {
var infowindow = new google.maps.InfoWindow();
var center = new google.maps.LatLng(site.Latitude, site.Longitude);
infowindow.setContent(
'<h3>' + site.SiteName + '</h3>' + '<p>' + site.Address1 + '<br/>' + site.Address2 + '<br/>' + site.City + ', ' + site.State + ' ' + site.ZipCode + '</p>');
infowindow.setPosition(center);
infowindow.open($scope.map);
$scope.findSelectedLocations(site.SiteName);
};
$scope.findSelectedLocations = function(SiteName) {
$scope.filteredData.forEach(function(itemElement, itemIndex) {
itemElement.Locations.forEach(function(locationElement, locationIndex) {
locationElement.Sites.forEach(function(siteElement, siteIndex) {
if (siteElement.SiteName == SiteName) {
console.log('match!');
console.log('itemIndex: ' + itemIndex);
console.table(itemElement);
$scope.$apply(function() {
$scope.filteredData == itemElement;
});
return false;
}
});
});
});
<div class="trials-item-outer-wrapper">
<div class="trials-item-wrapper" du-scroll-container>
<!-- start of row -->
<div class="trials-item {{class}}" ng-repeat="data in (filteredData = (dataObject | byCountry : selectRegion | byRegion : selectState | byCity : selectCity | filterBy:['Phase']: selectPhase | filterBy:['Compound']: selectCompound | filterBy:['TherapeuticArea', 'TherapeuticArea_2',]: selectTherapy : 'strict' | unique: 'Id' | orderBy:'Phase' : reverse)) track by $index "
ng-class="{'open':$index == selectedRow}" id="anchor-{{$index}}">
<div class="trials-item-cell-wrapper">
<div class="trials-item-cell">
<img ng-click="toggleOpen($index, data.Compound,data.Number)" ng-src="assets/img/phase{{ data.Phase}}.png" width="54" height="61" alt="Phase {{ data.Phase}}" class="trials-item-phase-icon">
</div>
<div class="trials-item-cell"><a ng-click="toggleOpen($index, data.Compound,data.Number)"><span class="compound">{{ data.Compound }}</span><br/>{{ data.Compound_2 }}</a>
</div>
<div class="trials-item-cell">
<a href="" ng-click="toggleOpen($index, data.Compound,data.Number)">
<p class="trial-title">{{ data.TitleShort }}</p>
<p>{{ data.Number }} {{ data.Status }}</p>
</a>
</div>
<div class="trials-item-cell">
<a href="" ng-click="toggleOpen($index, data.Compound,data.Number)">
{{ data.TherapeuticArea }}<span ng-if="data.TherapeuticArea_2">, {{ data.TherapeuticArea_2 }}</span>
</a>
</div>
<div class="trials-item-cell location-cell">
<span ng-if="data.Disclaimer">
<p>{{data.Disclaimer}}</p></span>
</div>
<div class="trials-item-cell cart-actions">
<div ng-if="!isInCart(data.Id)" class="add-to-cart">
<a href="" ng-click="addToCartModalOpen($index, data, data.Id)">
<img src="assets/img/cart-add.png" width="73" height="65" alt="Cart Add">
<span>Add to Cart</span>
</a>
</div>
<div ng-if="isInCart(data.Id)" class="remove-from-cart">
<a href="" ng-click="removeFromCart(data.Id)">
<img src="assets/img/cart-added.png" width="73" height="65" alt="Cart Add">
<span>Remove from Cart</span>
</a>
</div>
</div>
<div class="trials-item-cell">
<a ng-click="toggleOpen($index, data.Compound,data.Number)">
<p class="more-text"></p>
<div class="more glyphicon"></div>
</a>
</div>
</div>
<!-- trials-item-cell-wrapper -->
<div class="trials-tabs" ng-include="data.Url"></div>
</div>
<!-- end of ng-repeat -->
So the view uses the $scope.filteredData obj to display the list of filtered data. In $scope.showInfoWindow, I'm displaying an infowindow for a map pin that the user clicks on. I then pass the 'site.SiteName' value to the $scope.findSelectedLocations method to loop thru the $scope.filteredData object to find any matches to that location. This part works fine. I can console.table the data and see that itemElement is indeed showing the correct data when the map pin is click (via $scope.showInfoWindow() ).
When I'm having the issue is getting that updated data back in to the view.
In $scope.findSelectedLocations, I'm updating $scope.filteredData with the updated items in itemElement, but the view that displays $scope.filteredData isn't updating. As you can see below, I've tried wrapping that assignment in a $scope.$apply, but that doesn't work either.
No need for apply(), that's needed when something out of Angular's context needs to be rendered explicitly in a digest cycle.
May be there's a typo:
Instead of:
$scope.filteredData == itemElement;
Use:
$scope.filteredData = itemElement;
And try now.
Angular has two-way data binding. So whenever your model updates, views will automatically be get rendered. Nothing needs to be done explicitly. We have to have a watcher if we want to update the view/logic based on some change detection.

nested ng-repeat index not working || nested ng-click not working

if we create two or three comment with multiple replies to them the "helpful" link is causing problem when clicked it perform ng-click operation on the index with same number thus showing all the text with same index. how to resolve this nesting so that when a link is clicked only the respective text is shown
http://plnkr.co/edit/XS4Nro3sdIWMnopdgDYG?p=preview
the ng-click and ng-show operation are working through myDiscuss controller
var app = angular.module("myDiscuss", []);
app.controller("TabController", function($scope) {
$scope.subTab = null;
$scope.subLike=null;
$scope.selectSubLike = function (setTab) {
$scope.subLike=setTab;
}
$scope.selectSubTab = function(setTab){
$scope.subTab = setTab;
};
$scope.isSelectedSub = function(checkTab){
return $scope.subTab === checkTab;
};
$scope.isSelectedSubLike = function(checkTab){
return $scope.subLike===checkTab;
};
});
For html file look in the plunker link.
Helpful and Reply link are in the reply-link.html file
Here is a Plunker: http://plnkr.co/edit/PQ36lMXR1YOs8DP7WXMk?p=preview
What I did is added helpful: 0 to both comment and reply objects. Also added <p ng-if="object.helpful">{{ object.helpful }} </p> to comment-section.html and reply-box.html
Then when clicking on the helpful added a new function called increaseHelpful(object) where you increase the helpful variable by one on each click. Of course you need to make it that one user can only click it once but just for example :)
Get the index1 also in so you can get the reply box where you click the reply button. Use selectSubTab(index, index1) and then have two variables in $scope.subTab to check what is selected.
Edited from Konkko's plnkr http://plnkr.co/edit/lbn57aPTJQpgzMaQPW6t?p=preview
reply-box.html
<div id ="wrapper">
<form ng-submit="replysubmit()" ng-controller="BlockController">
<div class="clearfix" ng-if="isSelectedSub(index)">
<input type="textarea" tabindex="0"
style="overflow: auto; max-height: 350px; margin-top:1px;" class ="col-sm-8 col-md-8 col-lg-11" ng-model="reply.comment"
name="reply.comment" placeholder="Write a Reply" />
</div>
<blockquote ng-repeat="(index1,object) in replybox">
<h4>Name</h4>
<p>
{{object.comment}} {{index1+1}}
</p>
<p ng-if="object.helpful">{{ object.helpful }} </p>
<ul reply-links></ul>
<div class="clearfix" ng-if="isSelectedSub(index, index1)">
<input type="textarea" tabindex="0"
style="overflow: auto; max-height: 350px; margin-top:1px;" class ="col-sm-8 col-md-8 col-lg-11" ng-model="reply.comment"
name="reply.comment" placeholder="test" />
</div>
</blockquote>
</form>
</div>
reply-links.html:
<ul class="nav nav-pills">
<li>
<a href ng-click="increaseHelpful(object)" class="glyphicon ">Helpful</a>
</li>
<li>
<a href ng-click="selectSubTab(index, index1)" class="glyphicon" >Reply</a>
</li>
</ul>
JS:
$scope.subTab = {first: null, second: null};
$scope.selectSubTab = function(setTab, setTab1){
console.log(setTab);console.log(setTab1);
$scope.subTab = {first: setTab, second: setTab1};
};
$scope.isSelectedSub = function(checkTab, checkTab1){
return $scope.subTab.first === checkTab && $scope.subTab.second === checkTab1;
};

Directive changes CSS when element is active

I'm very new to Angular so I'm sure this isn't correct but I have a set of <li> elements which further contain links (individually, they're just navigation buttons for my page). What I'd like is to keep the specific button, say, "Home" highlighted a certain color while the user is on that page. So my html roughly looks like this...
<li class="active menuBar">
<a ui-sref="aap.configure.views" change-css="aap.isActive()">
<div class="row text-center">
<span class="glyphicon glyphicon glyphicon-cog" aria-hidden="true" style="font-size: 2.5em;"></span>
</div>
<div class="row">
<span class="glyphicon-class">Home</span>
</div>
</a>
</li>
I literally just wrote my first custom Directive yesterday so here's my second attempt at one...
app.directive( 'changeCss', [ '$location',
function ( ) {
return {
restrict: 'A',
scope: {
active: '&'
},
link: function( $scope, element, attrs ){
if( $scope.active ){
element.addClass( 'actives');
}
else {
element.addClass( 'inActives' );
}
}
};
}
] );
And my isActive() function looks like...
var active = false;
$scope.aap.isActive = function( ){
if ( active ){
active = false;
return true;
} else {
active = true;
return false;
};
};
Now, when I load up the page all the navigation buttons (Home, Save, etc.) are the color I'd like them to be. Clicking on a button, say, "Home" highlights that button in the color I'd like it to be. But, when I interact with that Home page at all, click an accordion element for instance, the color goes back to the "inactive" color. What am I doing wrong?
I'm not 100% sure for this. but I hope this might help you. If you want to set the active/inactive of your navigation bar base on your page.
I use ng-class for setting active of the navigation bar (see here https://docs.angularjs.org/api/ng/directive/ngClass) by passing the uri to the function getClass().
<div class="col-sm-3 col-md-2 sidebar" ng-controller="mainCtrl">
<ul class="nav nav-sidebar">
<li ng-class="{'active': getClass('/dashboard')}" >
<a href="/">
Dashboard
</a>
</li>
<li ng-class="{'active': getClass('/session')}">
<a ng-href="/session">
Sessions
</a>
</li>
</ul>
</div>
at my Controller I check the location path and sends boolean for activating/deactivating the ng-class
.controller('mainCtrl', ['$location','$scope', function ($location, $scope) {
$scope.getClass = function(path) {
if ($location.path().substr(0, path.length) == path) {
return true;
} else {
return false;
}
}
}]);

Give a value to an ng-model="searchText" input based on list item clicked in Angular JS

I created a list that is searchable with an input using angular.js (ng-model="searchText"). On click of the list elements you can pull the content of the selected item using {{selected | json}}. I want to apply this selected element as the value of the input when a list item is clicked.
I essentially want to create my own autocomplete that always displays a list of options, filters options while typing, and fills in the input on click of an option.
HTML
<html ng-app>
<section>
<div id="content-body" class="container search-page"><!-- begin content-body -->
<div id="content-frame" class="container"></div><!-- end content-frame -->
<section>
<div class="search-container">
<div class="search-wrapper">
<input type="search" class="input-from" autocomplete="off" placeholder="Search" ng-model="searchText" value="{{searchText}}">
</div>
</div>
</section>
<section>
<div ng-controller="ContentCtrl">
<ul class="list-group search">
<!--<li class="list-group-item group-title">
<span class="icon itinerary-icon"></span>
Popular Destinations
</li>-->
<a ng-click="setMaster(cities)" ng-repeat="city in cities | filter:searchText | limitTo:limit" href="#" class="list-group-item">{{city}}</a>
</ul>
</div>
</section>
</div><!-- end content-body -->
</html>
JS
function ContentCtrl($scope, $http) {
"use strict";
$scope.url = '../mobile-site/cities.json';
$scope.cities = [];
$scope.limit = 10; // max 10 cities loaded
$scope.fetchContent = function() {
$http.get($scope.url).then(function(response){
$scope.cities = response.data.cities;
});
}
$scope.fetchContent(); // build cities list
$scope.setMaster = function(city) {
$scope.searchText = city; // pull selected city using {{selected | json}}
}
}
JSON
{
"version": "082B6AF45261B81358E8F99F0FAEC4A4",
"cities": [
"A Friela Maside, Spain",
"A Gudina, Spain",
"AHA, Germany",
"AL, Norway"
]
}
I think you have a few mistakes in the code:
<div ng-model="chosen">
<a ng-click="setMaster(cities)" ng-repeat="cities in cities | filter:searchText | limitTo:limit" href="#" class="list-group-item">{{cities}}</a>
</div>
shoud be
<div ng-repeat="city in cities | filter:searchText | limitTo:limit">
<a ng-click="setMaster(city)" class="list-group-item">{{city}}</a>
</div>
then I think what you want is
$scope.setMaster = function(city) {
$scope.searchText = city;
}
Also, I'm not sure what the ng-model on the div is for, as far as I know it is used only for inputs, textareas and selects. See http://docs.angularjs.org/api/ng.directive:ngModel.
You probably want something like this fiddle -> http://jsfiddle.net/weSpW/3/.

Categories