I currently have this site - http://dev.5874.co.uk/scd-data/ where I have a dropdown which displays results from WP-API which I am pulling in through AngularJS.

It currently combines the two sets of results as they're separate URL's, the results are in categories within a custom post type so if both posts are 'tagged' in the same category chosen they display twice. I need a way to combine the two sets of results but only showing one of the posts - I hope this makes sense. I'm very new to API data and AngularJS and I imagine there is a much simpler way of doing this. Any help would be much appreciated. Here is a snippet of my code to show how it's currently working.

Thanks in advance!

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>

<style>

    .desc {display: none;}

</style>

<script type="text/javascript">
                    $(function(){
                              $('.selectOption').change(function(){
                                var selected = $(this).find(':selected').text();
                                //alert(selected);
                                $(".desc").hide();
                                 $('#' + selected).show();
                              }).change()
                    });
</script>


<script>

    var app = angular.module('myApp', []);

    app.controller('northWestCtrl', function($scope, $http) {
      var url = 'http://scd.blaze.wpengine.com/wp-json/posts?type=listings&filter[listing_area]=northwest';
      $http.get(url).then(function(data) {
        $scope.data = data.data;
      });
    });
</script>


         <select class="selectOption">
                        <option>Search by Region</option>
                        <option>NorthWest</option>
                        <option>NorthEast</option>
                        <option>Midlands</option>
                        <option>EastAnglia</option>
                        <option>SouthEast</option>
                        <option>SouthWest</option>
                        <option>Scotland</option>
                        <option>Wales</option>
                        <option>NorthernIreland</option>
                        <option>ChannelIslands</option>
       </select>


<div id="changingArea">


    <body ng-app="myApp">
                <div id="NorthWest" class="desc">

                <div  ng-controller="northWestCtrl">
                  <div ng-repeat="d in data">
                    <h2 class="entry-title title-post">{{d.title}}</h2>
                    <img src="{{d.acf.logo}}">
                    <div id="listing-contact">Contact: {{d.acf.contact}}, {{d.acf.position}}</div>
                    <div id="listing-address-1">
                      {{d.acf.address_1}}, {{d.acf.address_2}} {{d.acf.address_3}} {{d.acf.town}} {{d.acf.county}} {{d.acf.postcode}}
                    </div>
                    <div id="listing-phone">Telephone: {{d.acf.telephone}}</div>
                    <div id="listing-mobile">Mobile: {{d.acf.mobile}}</div>
                    <div id="listing-email">Email: {{d.acf.email}}</div>
                    <div id="listing-website">Website: <a href="{{d.acf.website}}">{{d.acf.website}}</a></div>
                    <div id="listing-established">Established: {{d.acf.established}}</div>
                    <div id="listing-about">About: {{d.acf.about}}</div>
                    <div id="listing-mailingaddress">Mailing Address: {{d.acf.mailing_address_}}, {{d.acf.mailing_address_2}}, {{d.acf.mailing_address_3}}, {{d.acf.mailing_town}}, {{d.acf.mailing_county}}, {{d.acf.mailing_postcode}}</div>
                    <div id="listing-directions">Directions: {{d.acf.directions}}</div>
                    <div id="scd-link"><a href="{{d.link}}">View on The Shooting Club Directory</a></div>
                  </div>
                </div>
              </div>
</body>
</div>

Here is a working code pen - http://codepen.io/anon/pen/yePYdq

share|improve this question
    
You'd better not mix jquery and angular.Use ng-show to show or hide a div – hirra Jan 18 '16 at 11:44
    
Besides,put your code into jsfiddle or codepen – hirra Jan 18 '16 at 11:50
    
I'm only using javascript for the dropdown function, but how would I use ng-show to do the same thing? I'm very new to AngularJS – Lucy Brown Jan 18 '16 at 13:18
    
@hirra a code pen - codepen.io/anon/pen/yePYdq – Lucy Brown Jan 18 '16 at 13:22
    
@LucyBrown Thanks for the codepen! I've given your question a shot below. – Julian V. Modesto Jan 22 '16 at 6:10
up vote 1 down vote accepted
+50

Angular is a great JavaScript front-end framework to choose, and you're off to a good start, but a lot of changes could be made. I've made some suggested changes for easier ways to do things below.

See this CodePen for all changes.

It looks like you've grasped the idea of ng-repeat, but there's definitely a lot of repeated HTML and JS in your view and controller, so let's see if we can do better.

  1. Let's try this without jQuery to avoid direct manipulation of the DOM. And instead of many controllers, we can do this with a single controller.

    <div ng-app="MyApp">
        <div ng-controller="MyController">
        ...
        </div>
    </div>
    <script type="text/javascript">
        var app = angular.module('MyApp', []);
        app.controller('MyController', ...);
    </script>
    
  2. For the dropdown, we'll use ng-repeat in our view and display the names of the shooting types from our model

    ...
    <select ng-model="selectedListing">
        <option
            ng-repeat="listingShootingType in listingShootingTypes"
            value="{{listingShootingType.name}}">
            {{listingShootingType.name}}
        </option>
    </select>
    ...
    <script type="text/javascript">
        ...
        // Our selections/filters
        $scope.listingShootingTypes = [
            'All',
            'Air Rifle/Air Pistol',
            'Clay',
            'ABT',
            'Double Trap',
            'English Skeet',
            'English Sporting',
            'Fitasc',
            'Olympic Skeet',
            'Olympic Trap',
            'Simulated Game',
            'Sport Trap/Compact',
            'Universal Trench',
            'ZZ/Helice',
            'Rifle',
            'Centrefire Target Rifle',
            'Gallery Rifle',
            'Muzzle Loading',
            'Practice Shotgun',
            'Smallbore Rifle'
        ];
        ...
    </script>
    
  3. With only one controller, we can still use ng-repeat for each listing.

    <div ng-repeat="d in data">
        <h2 class="entry-title title-post">{{d.title}}</h2>
        <div id="listing-image"><img src="{{d.acf.logo}}"></div>
        <div id="listing-contact">Contact: {{d.acf.contact}}, {{d.acf.position}}</div>
        <div id="listing-address-1">
            {{d.acf.address_1}}, {{d.acf.address_2}} {{d.acf.address_3}} {{d.acf.town}} {{d.acf.county}} {{d.acf.postcode}}
        </div>
        <div id="listing-phone">Telephone: {{d.acf.telephone}}</div>
        <div id="listing-mobile">Mobile: {{d.acf.mobile}}</div>
        <div id="listing-email">Email: {{d.acf.email}}</div>
        <div id="listing-website">Website: <a href="{{d.acf.website}}">{{d.acf.website}}</a></div>
        <div id="listing-established">Established: {{d.acf.established}}</div>
        <div id="listing-about">About: {{d.acf.about}}</div>
        <div id="listing-mailingaddress">Mailing Address: {{d.acf.mailing_address_}}, {{d.acf.mailing_address_2}}, {{d.acf.mailing_address_3}}, {{d.acf.mailing_town}}, {{d.acf.mailing_county}}, {{d.acf.mailing_postcode}}</div>
        <div id="listing-directions">Directions: {{d.acf.directions}}</div>
        <div id="scd-link"><a href="{{d.link}}">View on The Shooting Club Directory</a></div>
    </div>
    
  4. Finally... How do we only display listings that match our selected shooting type from the dropdown? We could use a custom Angular filter!

    ...
    <div ng-repeat="d in data | filter:isSelectedListing">
    ...
    <script type="text/javascript">
        ...
        // Let's define a custom Angular filter because the WordPress JSON is complex
        $scope.isSelectedListing = function(listing) {
            // Show nothing if nothing is selected
            if (angular.isUndefined($scope.selectedListing) || $scope.selectedListing == '') {
                return false;
            }
    
            // Show all if 'All' is selected
            if ($scope.selectedListing == 'All') {
                return true;
            }
    
            // If the shooting type we're looking for is present, show the listing.
            // To do this, we parse the WordPress JSON object model.
            if (angular.isDefined(listing.terms.listing_shooting_type)) {
                for (var i = 0; i < listing.terms.listing_shooting_type.length; i++) {
                    if (listing.terms.listing_shooting_type[i].name == $scope.selectedListing) {
                        return true;
                    }
                }
            }
            return false;
        };
        ...
    </script>
    

Hopefully this gives you an idea of how we better leverage ng-repeat + DRY :)

The entire CodePen is here.

share|improve this answer
1  
Thank you for this detailed answer, very helpful! I really appreciate it :-) – Lucy Brown Jan 22 '16 at 15:28

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.