1

I have a few select menus and I'm trying to get my custom filter to work with the dirPagination directive I'm using for pagination on my site. Seem like I'm missing something that is not getting the filtered array to reset and fill only the filter data that I need based on the selections. I did get the dupes error on repeat but adding track by $index does not do any good. Can someone tell me what I am missing to get the correct filtering to work?

Here is my plunker.

HTML:

<div class="form-group">
    <div class="col-sm-3 corpEvents-filters">
        <label for="sel1">Deadline Date</label>
        <br />
        <select class="form-control" id="sel1" ng-model="search.DeadlineDate" ng-options="filter.SelectItemValue as filter.SelectItemName for filter in sortFilters | filter:{FilterType:'Deadline Date'}">
            <option value="">Select One</option>
        </select>
    </div>

    <div class="col-sm-3 corpEvents-filters">
        <label for="sel2">Holdings</label>
        <br />
        <select class="form-control" ng-model="search.Holdings" ng-options="filter.SelectItemValue as filter.SelectItemName for filter in sortFilters | filter:{FilterType:'Holdings'}">
            <option value="">Select One</option>
        </select>
    </div>
    <div class="col-sm-3 corpEvents-filters">
        <label for="sel3">Type</label>
        <br />
        <select class="form-control" ng-model="search.eventType" ng-options="filter.SelectItemValue as filter.SelectItemName for filter in sortFilters | filter:{FilterType:'Type'} | orderBy: 'SelectItemName'">
            <option value="">Select One</option>
        </select>
    </div>
    <div class="col-sm-3 corpEvents-filters">
        <label for="sel4">Status</label>
        <br />
        <select class="form-control" id="sel4" ng-model="search.Status" ng-options="filter.SelectItemValue as filter.SelectItemName for filter in sortFilters | filter:{FilterType:'Status'}">
            <option value="">Select One</option>
        </select>
     </div>
 </div>

        <table class="table table-condensed">
          <thead>
            <tr>
              <th>Deadline Date</th>
              <th>Holding</th>
              <th>Type</th>
              <th>Status</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody dir-paginate="event in filteredEvents = (events | corpEventFilter:search) | itemsPerPage: 10" pagination-id="evt">
            <tr>
              <td width="15%">{{ event.DeadlineDate | date: 'MM/dd/yyyy' }}</td>
              <td width="35%">{{ event.Holding }}</td>
              <td width="20%">{{ event.Type | limitTo:20 }}{{event.Type.length > 20 ? '...' : ''}}</td>
              <td width="20%">{{ event.Status }}</td>
              <td>
                <a ui-sref="#">{{ event.Action }}</a>
              </td>
            </tr>

          </tbody>
          <tbody ng-if="filteredEvents.length === 0"><tr><td>No events found.</td></tr></tbody>
        </table>

      <div class="text-center">
        <dir-pagination-controls pagination-id="evt" boundary-links="true" on-page-change="pageChangeHandler(newPageNumber)" template-url="dirPagination.tpl.html"></dir-pagination-controls>
      </div>

JS:

 app.filter('corpEventFilter', function($filter) {
return function (items, search) {
if (!search) {
    return items;
}


var filtered = [];
var count = 0;

for (var i = 0; i < items.length; i++) {
  var item = items[i];

  if (search.DeadlineDate !== null) {
    // Return today's date and time
    var currentDate = new Date()
    var currentMonth = $filter('date')(currentDate, 'MM');
    var currentYear = $filter('date')(currentDate, 'yyyy');
    var currentMonthYear = currentMonth + currentYear;
    // Deadline Date
    var ddDate = new Date(item.DeadlineDate);
    var ddMonth = $filter('date')(ddDate, 'MM');
    var ddYear = $filter('date')(ddDate,'yyyy');
    var ddMonthYear = ddMonth + ddYear;

    //Selected Option
    if (search.DeadlineDate === 'This Year')
    {
      if (ddYear == currentYear)
      {
        filtered.push(item);
      } 
    }
    if (search.DeadlineDate === 'This Month')
    {
      if (ddMonthYear === currentMonthYear)
      {
        filtered.push(item);
      } 
    }
    if (search.DeadlineDate === 'This Week') 
    {
     var eventWeek = ddDate.getWeek();
     var eventWeekRange = eventWeek[0].toLocaleDateString() + ' to ' + eventWeek[1].toLocaleDateString();

     var currentWeek = new Date().getWeek();
     var currentWeekRange = currentWeek[0].toLocaleDateString() + ' to '+ currentWeek[1].toLocaleDateString();

     if (eventWeekRange === currentWeekRange) {
       filtered.push(item);
     }
    }
  }

  if (search.Holdings !== null) {
    if (item.HoldingType === search.Holdings) {
      filtered.push(item);
    }
  } 
  if (search.eventType !== null) {
    if (item.Type === search.eventType) {
      filtered.push(item);
    } 
  }
  if (search.Status !== null) {
    if (item.Status === search.Status) {
      filtered.push(item);
    }
  }
}

// If you choose 'Select One' it should undo the filter
if (search.DeadlineDate === null || search.Holdings === null || search.Status === null) {
    return items;
}

return filtered;
};

1 Answer 1

1

In your filter function, you are adding the same item to the filtered array every time it meets a condition. If the item meets n conditions it will be added to the results n times. This is why you are getting the dupes error.

for (item in items) {
  if (item meets condition1) {
    add item to results;
  }
  if (item meets condition2) {
    add item to results;
  }
  if (item meets condition3) {
    add item to results;
  }
  etc...
}

What you need to do is move to the next item if one of the conditions isn't met.

for (item in items) {
  if (item doesn't meet condition1) {
    move to next item;
  }
  etc...
  add item to results; // this will only be reached if the item meets all conditions
}

Using your code:

var filtered = [];

for (var i = 0; i < items.length; i++) {
  var item = items[i];

  if (search.DeadlineDate) {
    // this was lengthy so I left it out but I've updated it in the plunker
  }

  if (search.Holdings && search.Holdings !== item.HoldingType) {
    continue;
  } 

  if (search.eventType && item.Type !== search.eventType) {
    continue;
  }

  if (search.Status && item.Status !== search.Status) {
    continue;
  }

  filtered.push(item); // any item that reaches here meets all conditions
}

return filtered;

You checked if the search property was null but never specified what to do if undefined. Use the following pattern to check if the property exists and to then compare it.

if (search.Holdings && search.Holdings !== item.HoldingType) {
   continue;
}

Updated Plunker

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.