Trying to move completed tasks from one list to another - javascript

Here we have a tab with incompled tasks and the list is supposed to be attached to the first tab(all-taks). After the task is finished it is supposed to get deleted from first list and move to second one with completed tasks. And after you switch to second tab, all the completed ones should be there. I can't figure out the way to do it.
I hope I could get some help or some detailed explanation, 'cause I have been stuck on this for some time.
Here is an image for more clarification:
[1]: https://i.stack.imgur.com/Dy0KL.png
HTML code:
<body>
<div class="container">
<header>
<h1>To-Do List</h1>
<h4>Describe your list...</h4>
</header>
<form action="" class="todo-form">
<div class="form-wrapper">
<!-- action is where files will be sent after submitting -->
<input class="todo-input" type="text" placeholder="Add a task...">
</div>
<div class="form-wrapper">
<button class="todo-button" type="submit">Add</button>
</div>
</form>
<div class="todo-tabs">
<ul>
<li class="all-tasks active">
<span></span>All tasks (<span class="counter">0</span>)</span>
</li>
<li class="completed">
<span>Completed (<span class="counter">0</span>)</span>
</li>
</ul>
</div>
<div class="todo-list">
<div class="tabs-content" data-tab="1">
<ol class="undone-tasks"></ol>
</div>
<div class="tabs-content" data-tab="2">
<ol class="done-tasks"></ol>
</div>
</div>
</body>
JS code:
//Selectors
const todoForm = document.querySelector('.todo-form');
const todoInput = document.querySelector('.todo-input');
const todoButton = document.querySelector('.todo-button');
const tabs = document.querySelectorAll('.todo-tabs ul li');
const tabWrap = document.querySelector('.todo-tabs ul');
const undone = document.querySelector('.undone-tasks');
const done = document.querySelectorAll('.done-tasks');
//Event Listeners
tabWrap.addEventListener('click', tabs)
todoButton.addEventListener('click', addToDo);
//Functions
tabs.forEach(function (tab, tab_index) {
tab.addEventListener("click", function () {
tabs.forEach(function (tab) {
tab.classList.remove("active");
})
tabWrap.forEach(function (todoList, todoList_index) {
if (todoList_index == tab_index) {
todoList.style.display = "block";
}
else[
todoList.style.display = "none"
]
})
})
})
function addToDo(event) {
//Prevent form from submitting
event.preventDefault();
if (todoInput.value != "") {
const todoDiv = document.createElement('div');
todoDiv.classList.add('todo-div');
const inputCheckbox = document.createElement('input');
inputCheckbox.classList.add("checkbox-incompleted");
inputCheckbox.setAttribute('type', 'checkbox');
todoDiv.appendChild(inputCheckbox);
//Create li
const newToDo = document.createElement('li');
newToDo.classList.add('todo-item');
newToDo.insertAdjacentText("beforeend", todoInput.value);
todoDiv.appendChild(newToDo);
console.log(newToDo)
//Append to list
undone.appendChild(todoDiv);
//Clear todo input value
todoInput.value = "";
//Focusing after 1st input
todoInput.focus();
}
}
The commented area is what i tried to do for tabs and lists to switch, but it gives the following error:
Uncaught TypeError: tabWrap.forEach is not a function
at HTMLLIElement.<anonymous> (script.js:32:17)
(anonymous) # script.js:32
The error starts at the beggining of the tabWrap.forEach function. But I guess there could be other way to solve this

tabWrap is not useful for what you want: it is a single element. Instead, you'll want to iterate over the tab contents, which are identified by class tabs-content. It is those that you need to iterate and show or hide.
Then, to decide which contents to use, you may need to use that data-tab attribute you have in your HTML (not sure, since it is nowhere referenced).
Anyway, adapt as needed:
const tabContents = document.querySelectorAll('.tabs-content');
tabs.forEach(function (activeTab, activeIndex) {
activeTab.addEventListener("click", function (e) {
tabs.forEach(function (tab) {
tab.classList.toggle("active", tab == activeTab);
});
tabContents.forEach(function (tabContent) {
tabContent.style.display = tabContent.dataset.tab == activeIndex + 1 ? "" : "none";
});
})
})

As #Anurag Srivastava pointed out on comment, in your code this is how you get tab elements:
const tabs = document.querySelectorAll('.todo-tabs ul li');
const tabWrap = document.querySelector('.todo-tabs ul');
The method querySelector returns a single element, and querySelectorAll returns an iterable collection.
And this is why you're getting the error:
Uncaught TypeError: tabWrap.forEach is not a function
If you don't have to support internet explorer you could take a look at Element.insertAdjacentElement() to move elements from one tab to another.

Related

creat event listener for each product JS

I have to build an event listener that listens for a click to delete the product it's linked to; for this I was asked to use element.closest().
Here is the HTML that is being generated for each product:
<article class="cart__item" data-id="${product._id}" data-color="${chosenProduct.color}">
<div class="cart__item__img">
<img src="${product.imageUrl}" alt="${product.altTxt}">
</div>
<div class="cart__item__content">
<div class="cart__item__content__description">
<h2>${product.name}</h2>
<p>${chosenProduct.color}</p>
<p>${product.price}€</p>
</div>
<div class="cart__item__content__settings">
<div class="cart__item__content__settings__quantity">
<p>Qté : ${quantity}</p>
<input type="number" class="itemQuantity" name="itemQuantity" min="1" max="100" value="${quantity}">
</div>
<div class="cart__item__content__settings__delete">
<p class="deleteItem">Supprimer</p>
</div>
</div>
</div>
</article>
As you can see, the identity of the product is inside the article tag.
I launch my function with the event listener with a delay, to make sure the HTML is created, so that I can collect the button(s).
window.setTimeout(function deleteButton() {
const buttons = document.querySelectorAll(".deleteItem");
buttons.forEach((button) => {
button.addEventListener("click", deleteProduct);
});
}, 800);
With this code, each button responds to the function, but they only delete the first product.
Here is what the delete function looks like:
function deleteProduct() {
const itemToDelete = document.querySelector(".cart__item__content");
const idProductToDelete = itemToDelete.closest("article").getAttribute("data-id");
const colorProductToDelete = itemToDelete.closest("article").getAttribute("data-color");
const productToDelete = "product-" + idProductToDelete + "-" + colorProductToDelete;
//remove the item from local storage
localStorage.removeItem(productToDelete);
//remove from the html instantly
deleteHtml();
}
What I understand is that: element.closest() only works with querySelector() (I can't get it to work with getElements etc...), but querySelector() returns only the first element it finds.
How can I make this work?
function deleteProduct() {
const itemToDelete = event.target.querySelector(".cart__item__content");
const idProductToDelete = itemToDelete.closest("article").getAttribute("data-id");
const colorProductToDelete = itemToDelete.closest("article").getAttribute("data-color");
const productToDelete = "product-" + idProductToDelete + "-" + colorProductToDelete;
// //remove the item from local storage
localStorage.removeItem(productToDelete);
// //remove from the html instantly
deleteHtml();
}
Instead of using document.querySelector, you can use the click event's target element. closest would work for it.
or you can directly use
const idProductToDelete = event.target.closest("article").getAttribute("data-id");

JavaScript removing list elements by class name

I am having an issue with my javascript function in regards to removing elements. What I have below is two lists inside a div menu with each <li> marked by a class according to the category of drink and the drinks themselves. I also have a button that opens a modal box where the user would type in a drink category to remove. I decided to approach this by naming <li> with classes by the drink category and then taking a js function to get the elements by class name from the input text node and to remove those elements with what the user typed.
<div class = "menu">
<ul>
<li class = "coffee">french press</li>
<li class = "tea"><a href="#">english breakfast/a></li>
<li class = "milk">whole</li>
</ul>
<ul>
<li class = "coffee">dark roast</li>
<li class = "tea">green tea</li>
<li class = "milk">two percent</li>
</ul>
</div>
<button type="button" id ="openmodal">Click Me!</button>
<div id="myDeleteModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<h1 class="modal-title">
<b>Type the drink category you want to remove </b>
</h1>
<input id="deletedrinktext" type="text" />
<button id="delete">Remove</button>
<button type="button" class="btn btn-defaultdeletedrink" id="closedbtn" data-dismiss="modal" onclick="">Close</button>
</div>
</div>
<script>
var modal = document.getElementById("myDeleteModal");
// Get the button that opens the modal
var btn = document.getElementById("openmodal");
var closebtn = document.getElementById("closedbtn");
// When the user clicks the button, open the modal
btn.onclick = function () {
modal.style.display = "block";
}
closebtn.onclick = function (event) {
modal.style.display = "none";
}
</script>
<script>
(function () {
document.querySelector('#delete').addEventListener('click', function () {
let inputRemover = document.querySelector('#deletedrinktext');
let itemRemover = document.createTextNode(inputRemover.value);
let listRemover = document.getElementsByClassName(itemRemover);
for (var i = 0; i < listRemover.length; i++) {
if (document.contains(listRemover)) {
listRemover[i].remove();
}
}
inputRemover.value = ""; // clear input
});
})();
</script>
So what I want to replicate is a user would open the modal box, type in coffee and click remove. This would remove from the document the following two elements:
<li class = "coffee">french press</li>
<li class = "coffee">dark roast</li>
This function isn't working so far and I am not sure if there is an error in my JS in getting each element or if going with the class approach is not the way to go about it? When I type in the name of the category just like written in my HTML, the element in the list still displays.
remove() is not a function of Array in javascript. I think your best approach would be to just not display the elements you want to remove. To do just change your handler function to this:
let inputRemover = document.querySelector('#deletedrinktext');
let listRemover = document.getElementsByClassName(inputRemover.value);
for (let i = 0; i < listRemover.length; i++) {
if (document.contains(listRemover[i])) {
listRemover[i].style.display = 'none';
}
}
JSFiddle to try it out without modal functionality.
This also helps you if you maybe want to reset the list. To do so, just set the display property on every element to block.
Also, I don't knwo if it is a copy paste issue but the a at english breakfast is missing a < in the closing tag.

Can't print correct innerHTML message within a nested function

I'm working on a recipes page where you have a series of buttons and posts that are interconnected. The buttons have names of recipe categories such as Pie and Cake. When you click on a 'Pie' button, you are only shown the posts that are categorized as 'Pie'. Both the buttons and the posts have data attributes that have their recipe category on there.
I am able to get this to work, however, I'm having issues for when you click on a recipe category button, and there are no corresponding posts. For this, I created an empty '#message' div that would output a message if there were no recipe posts found, and an empty string if there were recipe posts.
When I click on a recipe button that does have posts, I get the 'No Recipes' text in the message. Also weird that it looks like it's applying the correct message only to the last button/post which in this example is 'Cake'.
Can someone explain why this is not working? I get it's probably a scope/closure issue, but I'm unsure what's going on.
//BUTTONS
<section>
<button class="recipe_button" data-btncategory="Pie">
Pie
</button>
<button class="recipe_button" data-btncategory="Cake">
Cake
</button>
</section>
//POSTS
<div id="message"></div>
<section class="recipe" data-postcategory="Pie">
<h2>Pie Recipe</h2>
</section>
<section class="recipe" data-postcategory="Cake">
<h2>Cake Recipe</h2>
</section>
let posts = document.querySelectorAll(".recipe");
let postsArr = Array.from(posts);
let btn = document.querySelectorAll(".recipe_button");
let btnArray = Array.from(btn);
let message = document.getElementById("message");
btnArray.forEach((button) => {
button.onclick = (el) => {
let match = el.target.dataset.btncategory;
postsArr.filter(function(post, i) {
if (post.dataset.postcategory == match) {
posts[i].style.display = "grid";
<-- message not working properly -->
message.innerHTML = "";
} else {
posts[i].style.display = "none";
<-- message not working properly -->
message.innerHTML = "Sorry No Recipes Available";
}
});
}
});
look at how your filter is running. you'll always get ones that match and ones that don't - so both the if and the else code will always run
What you want to do is hide/display posts in the filter, returning true for displayed and false when hidden
That way, the resulting array length will be 0 if no match, and 1 or more if there is a match
Then another if/else after determining if there is anything displayed to show/hide the message
let posts = document.querySelectorAll(".recipe");
let postsArr = Array.from(posts);
let btn = document.querySelectorAll(".recipe_button");
let btnArray = Array.from(btn);
let message = document.getElementById("message");
btnArray.forEach((button) => {
button.onclick = (el) => {
let match = el.target.dataset.btncategory;
let found = postsArr.filter(function(post) {
if (post.dataset.postcategory == match) {
post.style.display = "grid";
return true;
} else {
post.style.display = "none";
return false;
}
}).length;
message.innerHTML = found ? "" : "Sorry No Recipes Available";
}
});
<section>
<button class="recipe_button" data-btncategory="Pie">
Pie
</button>
<button class="recipe_button" data-btncategory="Cake">
Cake
</button>
</section>
//POSTS
<div id="message"></div>
<section class="recipe" data-postcategory="Pie">
<h2>Pie Recipe</h2>
</section>
<section class="recipe" data-postcategory="Cake">
<h2>Cake Recipe</h2>
</section>
Having said all that, the message would NEVER display Sorry No Recipes Available since your buttons guarantee that there will be one displayed
Here's a straightforward way to make your idea work.
It uses an event listener with event delegation.
See the in-code comments for further clarifications.
// Identifies DOM elements
const
btnsDiv = document.getElementById("btns"),
posts = [...document.getElementsByClassName("recipe")],
message = document.getElementById("message");
// Calls `filterPosts` when btnsDiv is clicked
btnsDiv.addEventListener("click", filterPosts);
// Defines `filterPosts`
function filterPosts(event){
// Ignores irrelevant clicks
if(!event.target.classList.contains("btn")){ return; }
// Shows message while there is no match
let match = false;
message.classList.remove("hidden");
// Remembers category
const category = event.target.dataset.category;
// Iterates through recipes
posts.forEach( (post) => {
// Hides recipe until it matches
post.classList.add("hidden");
// If recipe matches, shows it and notes the match
if(post.dataset.category == category) {
post.classList.remove("hidden");
match = true;
}
});
// If any match occurred, hides message
if(match == true){
message.classList.add("hidden");
}
}
.hidden{ display: none; }
<div id = "btns">
<button class="btn" data-category="Pie">Pie </button>
<button class="btn" data-category="Cake"> Cake </button>
<button class="btn" data-category="Pasta"> Pasta </button>
</div>
<div id="message" class="hidden">Sorry No Recipes Available</div>
<div class="recipe hidden" data-category="Pie">
<h2>Pie Recipe 1</h2>
</div>
<div class="recipe hidden" data-category="Cake">
<h2>Cake Recipe 1</h2>
</div>
<div class="recipe hidden" data-category="Cake">
<h2>Cake Recipe 2</h2>
</div>

Filter data in ng-repeat to display only the clicked item with Angularjs

Please help a little bit.
I have a list of 7 events displayed already with Angularjs. I'd like when I click on the <h2> (the event name) of some event, to open an ovelay that displays the same data from the database but only for this event which is clicked.
I'm sure that 'filter' will do the work but it seems I'm doing something wrong.
Here is my code. The ng-app and ng-controller are in the <main> tag.
Angularjs version: 1.7.9
My Html:
<main ng-app="eventsApp" ng-controller="eventsCtrl">
<!-- Overlay that holds and displays a single event -->
<div>
<div ng-repeat="x in singlePageEvent | filter:hasName(x.eventName)">
<div>
<img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
<h2 class="event-name">{{x.eventName}}</h2>
<p>{{x.eventTime}}</p>
<p>{{x.eventPlace}}</p>
</div>
</div>
</div>
<!-- A list with all the events -->
<div ng-repeat="x in events">
<div>
<img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
<h2 ng-click="singleEventOpen(x)" class="event-name">{{x.eventName}}</h2>
<p>{{x.eventTime}}</p>
<p>{{x.eventPlace}}</p>
</div>
</div>
</main>
My script:
let eventsApp = angular.module('eventsApp', []);
this filter below is not working at all. It continues to show all the events.
eventsApp.filter('hasName', function() {
return function(events, evName) {
var filtered = [];
angular.forEach(events, function(ev) {
if (ev.eventName && ev.eventName.indexOf(evName) >-1) {
filtered.push(ev);
}
});
return filtered;
}
});
eventsApp.controller('eventsCtrl', function($scope, $http) {
let x = window.matchMedia("(max-width: 450px)");
let singleEventOverlay = angular.element(document.querySelector('div.single-event.overlay'));
let singleEvent = singleEventOverlay;
function responsiveEventImages(x) { //this displays the list with events
if (x.matches) {
$http.get('./includes/events_res.inc.php').then(function(response) {
$scope.events = response.data.events_data;
});
} else {
$http.get('./includes/events.inc.php').then(function(response) {
$scope.events = response.data.events_data;
});
}
}
...and then by invoking singleEventOpen() the overlay appears, but it displays all the data, not just the clicked event
$scope.singleEventOpen = function(singleEvent) {
let clickedEvent = singleEvent.eventName; //I got the value of each h2 click thanx to #georgeawg but now what?
console.log("Fetching info for ", singleEvent.eventName);
$http.get('./includes/single_event.inc.php').then(function(response) {
$scope.singlePageEvent = response.data.events_data;
});
singleEventOverlay.removeClass('single-event-close').addClass('single-event-open');
}
});
The php file with the database extraction is working fine so I won't display it here.
What should I do to make the overlay display only the event which <h2> is clicked?
Here is a pic of the list with events
Here is a pic of the overlay
Thanx in advance.
EDITED
I got the value of each h2 click thanx to #georgeawg but now what?
UPDATE
Hey, thanx a lot #georgeawg . After many attempts I finally did this:
$scope.singleEventOpen = function(singleEvent) {
$http.get('./includes/single_event.inc.php').then(function(response) {
let allEvents = response.data.events_data;
for (var i = 0; i < allEvents.length; i++) {
singleEvent = allEvents[i];
}
});
console.log('Fetching data for', singleEvent);
$scope.ex = singleEvent;
});
And it works well.
Change the ng-click to pass an argument to the singleEventOpen function:
<div ng-repeat="x in events">
<div>
<img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
<h2 ng-click="singleEventOpen(x)" class="event-name">{{x.eventName}}</h2>
<p>{{x.eventTime}}</p>
<p>{{x.eventPlace}}</p>
</div>
</div>
Then use that argument:
$scope.singleEventOpen = function(singleEvent) {
console.log("Fetching info for ", singleEvent.eventName);
//...
//Fetch and filter the data
$scope.ex = "single item data";
}
Adding an argument is the key to knowing which <h2> element was clicked.
Update
Don't use ng-repeat in the overlay, just display the single item:
<!-- Overlay that holds and displays a single event -->
̶<̶d̶i̶v̶ ̶n̶g̶-̶r̶e̶p̶e̶a̶t̶=̶"̶x̶ ̶i̶n̶ ̶s̶i̶n̶g̶l̶e̶P̶a̶g̶e̶E̶v̶e̶n̶t̶ ̶|̶ ̶f̶i̶l̶t̶e̶r̶:̶h̶a̶s̶N̶a̶m̶e̶(̶x̶.̶e̶v̶e̶n̶t̶N̶a̶m̶e̶)̶"̶>̶
<div ng-if="ex"">
<div>
<img ng-src="{{ex.eventImgSrc}}" alt="{{ex.eventImgName}}"/>
<h2 class="event-name">{{ex.eventName}}</h2>
<p>{{ex.eventTime}}</p>
<p>{{ex.eventPlace}}</p>
</div>
</div>

jQuery Search Function

Hi i'm building a project which has a page navigation and search bar in jQuery.
I can't get my search function to work correctly and I'm not certain if it's a problem with the ID element or the each function. I'm getting the ("Sorry, no student's found!") message for anything that is or isn't a match. So i think there could be a problem with the if statement looking for a match in search function--but not sure.
I'm dynamically adding a search box to my html like this:
function appendSearchBox(){
var search = "<div class='student-search'><input id='search' placeholder='Search for students...'><button>Search</button></div>"
$(".students").after(search);
// Add click event handler
$("button").click(function() {
searchList();
});
}
this is what my html looks like for a list of students:
<div class="page">
<div class="page-header cf">
<h2 class="students">Students</h2>
</div>
<ul class="student-list">
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/67.jpg">
<h3>iboya vat</h3>
<span class="email">iboya.vat#example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 07/15/15</span>
</div>
</li>
</ul>
And then here is the actual search function:
var listStudents = $(".student-list li");
var numStudents = listStudents.length;
function searchList() {
var matched = [];
// Obtain the value of the search input
input = $("#search").val()
// remove the previous page link section
$('.pagination').hide();
// Loop over the student list, and for each student…
listStudents.each(function(){
// ...obtain the student’s name…
var name = $(this).find("h3").val();
// ...and the student’s email…
var email = $(this).find(".email").val();
// ...if the search value is found inside either email or name…
if (name.includes(input) || email.includes(input)) {
// ...add this student to list of “matched” student
matched.push($(this).parent());
}
});
// If there’s no “matched” students…
if (matched.length === 0){
// ...display a “no student’s found” message
var message = ("Sorry, no student's found!");
$(".student-list").hide();
$(".student-list").after(message);
if (matched.length > 10) {
// ...call appendPageLinks with the matched students
appendPageLinks(matched);
}
// Call showPage to show first ten students of matched list
showPage(1, matched);
}
}
adding functions which actually show the students and add navigation
function showPage(pageNum, listStudents) {
// first hide all students on the page
pageNum = parseInt(pageNum);
listStudents.hide();
// Then loop through all students in our student list argument
listStudents.each(function(index){
// if student should be on this page number
if ((index >= ((pageNum*10)-9)) && (index <= (pageNum*10))) {
// show the student
$(this).show();
}
});
}
function getNumPages(numStudents){
numPages = Math.ceil(numStudents/10);
return numPages;
}
function appendPageLinks(numStudents) {
// determine how many pages for this student list
pages = getNumPages(numStudents);
// create a page link section
var nav = "<div class='pagination'><ul>"
for (i=1; i<pages+1; i+=1){
nav += ("<li>" + "" + i + "" + "</li>");
};
nav += ("</ul></div>");
$(".student-list").after(nav);
// define what happens when you click a link
var active = $('.pagination a').click(function(){
// Use the showPage function to display the page for the link clicked
var id = $(this).attr('id');
showPage(id,listStudents);
// mark that link as “active”
active.removeClass('active');
$(this).addClass("active");
});
}
here is how i am calling the functions:
appendSearchBox();
showPage(1, listStudents);
appendPageLinks(numStudents);
UPDATE -- I have changed the code to remove the val and put in to grab the text.
Not sure what issue is but it appears if i have a correct match--it is working (since pagination disappears) but the students do not change on the page. If there is no match then I get the error message, but the error console is saying
Uncaught TypeError: listStudents.hide is not a function
at showPage (main.js:8)
I'm not sure if this is somehow related to how I am passing the 'matched' list?
h3 and span tags have no value, but text content, so replace:
var name = $(this).find("h3").val();
// ...and the student’s email…
var email = $(this).find(".email").val();
with:
var name = $(this).find("h3").text();
// ...and the student’s email…
var email = $(this).find(".email").text();
You are using val() method to read inner text of h3 and span (email). It should be text(). Also you are appending message after the student list every time you couldn't find a student. You could have used one span tag and hide/show based on the search results.
function appendSearchBox() {
var search = "<div class='student-search'><input id='search' placeholder='Search for students...'><button>Search</button></div>"
$(".students").after(search);
// Add click event handler
$("button").click(function () {
searchList();
});
}
$(document).ready(function () {
appendSearchBox();
});
function searchList() {
var listStudents = $(".student-list li");
var numStudents = listStudents.length;
$(".student-list").show();
$("#message").hide();
var matched = [];
// Obtain the value of the search input
input = $("#search").val()
// remove the previous page link section
$('.pagination').hide();
// Loop over the student list, and for each student…
listStudents.each(function () {
// ...obtain the student’s name…
var name = $(this).find("h3").text();
// ...and the student’s email…
var email = $(this).find(".email").text();
// ...if the search value is found inside either email or name…
if (name.includes(input) || email.includes(input)) {
// ...add this student to list of “matched” student
matched.push($(this).parent());
}
});
// If there’s no “matched” students…
if (matched.length === 0) {
// ...display a “no student’s found” message
var message = ("Sorry, no student's found!");
$(".student-list").hide();
$("#message").show();
if (matched.length > 10) {
// ...call appendPageLinks with the matched students
appendPageLinks(matched);
}
// Call showPage to show first ten students of matched list
showPage(1, matched);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="page">
<div class="page-header cf">
<h2 class="students">Students</h2>
</div>
<ul class="student-list">
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/67.jpg">
<h3>iboya vat</h3>
<span class="email">iboya.vat#example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 07/15/15</span>
</div>
</li>
</ul>
<span id="message" style="display:none;"><br/>Sorry, no student's found!</span>
</div>

Categories