By Md. Sabuj Sarker | 4/6/2018 | General |Beginners

Angular 5 To-Do List App - Part 9

Angular 5 To-Do List App - Part 9

In the previous articles we implemented case insensitive filtering and clearing logic. In this article we will add more features to our to-do application. The code of the previous article can be found in the article itself, and the complete project can be found in the Github repository Learn Angular With Sabuj. Browse to the branch named todo-app-part-8 to get the complete project code of the previous article. To get the complete project of the current article browse the branch named todo-app-part-9.

The task in this article is more of a logical task and you need to have enough patience to follow it. Otherwise, you will lose your focus in the middle.

Highlighting Filtered Part of Tasks

We can filter our tasks now with keywords. But, we do not have any visual indication in the filtered task list to indicate which part of the title matched. We can provide a visual indication by making that part bold as we see them on search engine results. So, we intend to put the matched filter_by text of task titles inside b tags to make it bold.

In our code we will need the lowercase version of the title repeatedly and converting a single text to lowercase repeatedly without any added benefit is not a good thing to do. So, we are going to put that inside a variable:

let title_lower = title.toLowerCase();

We will also need the length of the filter_by text and the the title:

let filter_len = this.filter_by.length;
let title_len = title.length;

We can split our original title into three different parts that are start, middle, and end. We will use the substr method of string to extract those parts. We want to find the first index where the filter_by started to match. To get it we can use the indexOf method of string:

let start_idx = title_lower.indexOf(this.filter_by);

We will also need the index where the filter_by text stopped matching. This can be calculated by the start index and adding the length of the filter text:

let end_idx = start_idx + filter_len;

We will apply substr on the title string. To get the start part of the string we can code like below:

let start = title.substr(0,  start_idx);

The start part must begin at zero and end at where the filter_by started matching. We can use start_idx as the length of the substring.

The middle part can be extracted by the start index and the length of the filter text:

let middle = title.substr(start_idx, filter_len);

In the same way the end can be extracted with end_idx and the length of the title.

let end = title.substr(end_idx, title_len);

At the end we will construct a new title with it, with bold tags, by joining the three parts:

let converted_title = start + "<b>" + middle + "</b>" + end;

So, the complete code of filterTasks() will look like below:

filterTasks(){
   let filtered_tasks: Array<Task> = [];
   for(let idx=0; idx < this.tasks.length; idx++){
     let task = this.tasks[idx];
     let title = task.title;
     let title_lower = title.toLowerCase();
     if (title_lower.includes(this.filter_by)){
       let filter_len = this.filter_by.length;
       let title_len = title.length;

       let start_idx = title_lower.indexOf(this.filter_by);
       let end_idx = start_idx + filter_len;

       let start = title.substr(0,  start_idx );
       let middle = title.substr(start_idx, filter_len);
       let end = title.substr(end_idx, title_len);

       let converted_title = start + "<b>" + middle + "</b>" + end;

       filtered_tasks.push(
         <Task>{
           title: converted_title,
           is_canceled: task.is_canceled,
           f_idx: idx
         }
       );
     }
   }

   this.filtered_tasks = filtered_tasks;
 }

If you go to the browser you will see that it is showing raw tags instead of making them bold. This is very normal behavior. Angular sanitizes interpolated strings before inserting them into the document. To overcome this we need to use innerHTML property.

So, instead of interpolation in two places we will use innerHTML property binding in two td elements.

So, we can do it like follows:

<td *ngIf="task.is_canceled; else elseTd" [innerHTML]="'<s>' + task.f_idx + 1 + '.' + task.title + '</s>'">
</td>

But this would be the wrong approach—task numbering will be messed up. When you add a number and a string, the result is a string. So, if you add index 1 and number 1, it will become 11. So, we need to enclose the addition of task.f_idx + 1 inside parentheses. Our code for both the if and else parts in the template should look like below:

<td *ngIf="task.is_canceled; else elseTd" [innerHTML]="'<s>' + (task.f_idx + 1) + '.' + task.title + '</s>'">
</td>
<ng-template #elseTd>
   <td [innerHTML]="(task.f_idx + 1) + '.' + task.title">

   </td>
</ng-template>

Go and open your browser, make various updates to your to-do list, filter with keywords and see if the filtered titles are becoming bold in places. Yes, it is working perfectly on my machine. We have just completed another feature of our to-do application.

Conclusion

Our to-do application code is gradually becoming more and more complex. Still, we are trying to keep it manageable. If you do not remain aware of what you are doing and what you intend to do next, you will lose track really soon. Create the complete application from scratch again and again to understand what we have done in every step. Keep practicing to master Angular. If you have any questions, create an issue on the Github repository Learn Angular with Sabuj and I will try my best to help you.

 

Previous article: Angular 5 to do list app - Part 8

Next article: coming soon!

 

About the Author

My name is Md. Sabuj Sarker. I am a Software Engineer, Trainer and Writer. I have over 10 years of experience in software development, web design and development, training, writing and some other cool stuff including few years of experience in mobile application development. I am also an open source contributor. Visit my github repository with username SabujXi.

By Md. Sabuj Sarker | 4/6/2018 | General

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Recent Stories

Top DiscoverSDK Experts

User photo
3355
Ashton Torrence
Web and Windows developer
GUI | Web and 11 more
View Profile
User photo
3220
Mendy Bennett
Experienced with Ad network & Ad servers.
Mobile | Ad Networks and 1 more
View Profile
User photo
3060
Karen Fitzgerald
7 years in Cross-Platform development.
Mobile | Cross Platform Frameworks
View Profile
Show All
X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now