Select elements with data-attribute date value older than current server date - javascript

I have a list of events that each have a custom data attribute containing a date:
<ul class="event-list">
<li class="event-item" data-event-date="20150218"></li>
<li class="event-item" data-event-date="20150522"></li>
<li class="event-item" data-event-date="20150928"></li>
</ul>
<ul class="old-event-list">
</ul>
What I'm trying to do is select all of the li.event-item elements within ul.event-list whose data-event-date attribute is older than the current (server time) date, and then move them to ul.old-event-list.
I know i can use appendTo to move the elements, but I have no idea how to select only the elements with an older date attribute than whatever the current server date is.
Any advice is greatly appreciated!

You could iterate over the elements and use the .filter() method to return elements whose data-event-date attribute value is greater/less than a certain value.
Then you would chain the .appendTo() method in order to append the returned elements.
Example Here
$('.event-list .event-item[data-event-date]').filter(function () {
return $(this).data('event-date') > 20150522;
}).appendTo('.old-event-list');
Of course you could dynamically retrieve the current date in JS rather than hardcoding one.

If you could use a date format that the Date object understands then you could rather easily do it like this:
$(function () {
var now = new Date();
var old = $(".old-event-list");
$(".event-list .event-item").each(function () {
var date = new Date($(this).data("event-date"));
if (date < now) {
$(this).appendTo(old);
}
});
});
How to parse a date formatted as 20150522 is a question all its own. It would be much easier to just use a format that Javascript understands, such as 2015-05-22. In PHP it would be date('Y-m-d', $time).

Try
$("[data-event-date^=2015]").map(function(i, el) {
return Number($(el).data("event-date")) > (new Date()).toJSON()
.replace(/[^\d]/g, "").slice(0, 8)
? $(".old-event-list").append(el) : null
});
$("[data-event-date^=2015]").map(function(i, el) {
return Number($(el).data("event-date")) > (new Date()).toJSON().replace(/[^\d]/g, "").slice(0, 8) ? $(".old-event-list").append(el) : null
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="event-list">
old list
<li class="event-item" data-event-date="20150218">old</li>
<li class="event-item" data-event-date="20150522">new</li>
<li class="event-item" data-event-date="20150928">new</li>
</ul>
<ul class="old-event-list">
new list
</ul>

Try the following code
function pad(number, length) {//small function to pad a number with leading zeros
var str = '' + number;
while (str.length < length) {
str = '0' + str;
}
return str;
}
$('.event-item').each(function() {
var edate = $(this).attr('data-event-date'); // get the value from data-event-date attribute
var fdate = new Date();
var year = fdate.getFullYear();
var month = fdate.getMonth();
var day = fdate.getDate();
var now = year;
if(day<=9) {
now += pad(day,2);
}
if(month<=9) {
now += pad(month,2);
}
if(now>edate) {
$('.old-event-list').html('<li class="event-item">'+$(this).text()+'</li>'); // put the old dates in old eventList
$(this).remove(); // remove item from current list
}
});
FIDDLE
http://jsfiddle.net/8coakc37/1/

Related

How to check when input value is changed?

How can i check when a value on input is changed.
I have a calendar and when i click on calendar it changes the value on input , but when im trying to see if it has changed its not working. i have tried AddEventListener, also jquery on change, also i sent a function on change to call it but none of them is working.
<input type="text" id="date" class="date" onchange="changed()" name="" >
function changed(){
alert("hello world");
}
Main js file for creating the calendar :
This function creates the calendar on my php file .
And then when on click it gets the value on the input with id #date
But When im trying to see if value has changed it is not working .
// Initialize the calendar by appending the HTML dates
function init_calendar(date) {
$(".tbody").empty();
$(".events-container").empty();
var calendar_days = $(".tbody");
var month = date.getMonth();
var year = date.getFullYear();
var day_count = days_in_month(month, year);
var row = $("<tr class='table-row'></tr>");
var today = date.getDate();
// Set date to 1 to find the first day of the month
date.setDate(1);
var first_day = date.getDay();
// 35+firstDay is the number of date elements to be added to the dates table
// 35 is from (7 days in a week) * (up to 5 rows of dates in a month)
for(var i=0; i<35+first_day; i++) {
// Since some of the elements will be blank,
// need to calculate actual date from index
var day = i-first_day+1;
// If it is a sunday, make a new row
if(i%7===0) {
calendar_days.append(row);
row = $("<tr class='table-row'></tr>");
}
// if current index isn't a day in this month, make it blank
if(i < first_day || day > day_count) {
var curr_date = $("<td class='table-date nil'>"+"</td>");
row.append(curr_date);
}
else {
var monthplusone = months[month];
var curr_date = $("<td class='table-date' id='"+day+"-"+monthplusone+"-"+year+"'>"+day+"</td>");
var events = check_events(day, month+1, year);
if(today===day && $(".active-date").length===0) {
curr_date.addClass("active-date");
let x = document.getElementById('date').value=day+"-"+monthplusone+"-"+year;
$('.table-date').ready(function () {
x.value;
});
show_events(events, months[month], day);
}
// If this date has any events, style it with .event-date
if(events.length!==0) {
curr_date.addClass("event-date");
}
// Set onClick handler for clicking a date
$('.table-date').on('click', function () {
document.getElementById('date').value = $(this).attr('id');
});
curr_date.click({events: events, month: months[month], day:day}, date_click);
row.append(curr_date);
}
}
// Append the last row and set the current year
calendar_days.append(row);
$(".year").text(year);
}
Notice that change is actually triggered when the input is not focused anymore.
document.getElementById("date").addEventListener("change", function () {
alert("hello world");
});
<input type="text" id="date" class="date" name="">
This works. Not sure where you're running into an issue.
function changed(){
console.log("hello world");
}
<input type="text" id="date" class="date" onchange="changed()" name="" >
EDIT: Shortened version of init_calender() for others interested in answering:
function setDate() {
document.getElementById("date").value = '19-Dec-2021'
}
I basically agree with #Spankied in that you should try and shorten your code to the point where you are having the issue. However, after looking at your code it seems to me that you want the following function
$('.table-date').on('click', function () {
document.getElementById('date').value = $(this).attr('id');
});
to not only change the value in your #date input but also trigger its change event-handler function. You can do that by changing it to something like
$('.table-date').on('click', function () {
document.getElementById('date').value = $(this).attr('id');
$("#date" ).change();
});
jQuery.change() without any arguments will trigger a predefined "change"-event on the DOM-object that is selected by the jQuery-object.
You can use js to do that:
let x = $(...) //select the input box
let val = x.value;
function repeat() {
if (val !== x.value) {
change()
}
}
setInterval(repeat, 100)
This checks if the result is the same.
This might make your site a bit slow and it might look odd but this will work in just every case
<script>
let Oldvalue = $('.date')[0].val();
setInterval(() => {
let currentValue = $('.data')[0].val()
if (Oldvalue != currentValue){
//do whatever but in end write this
Oldvalue = currentValue;
}
}, 10);
</script>

Javascript return list of all dates in month and seperate mondays

I wonder if someone can help me, I've done my best in trying to get as far as I can, but some help would really be great, if not help, then just some advice, I'm slowly learning.
As advice from someone, I have tried to include as much of my code as possible.
So I have the following code
var my_dates = function(start, end)
{
var start = new Date(start);
var end = new Date(end);
var arr = new Array();
var dt = new Date(start);
while (dt <= end)
{
arr.push(new Date(dt));
dt.setDate(dt.getDate() + 1);
}
return arr;
}
var dates_array = my_dates('2021-02-02', '2021-02-23');
and if I do console.log(dates_array ) it returns a list of dates between the two defined dates, and this is great.
If you think my code is over the top, I'm open to learning a better way.
But what I wanted to do, is expand this, so rather than returning dates between those 2 dates, so in the case of Feb, it would return all dates starting from the 1st and up until the 28th.
I then have this HTML
<div id="start_dates">
<ul class="monday_dates"></ul>
</div>
<div id="all_dates">
<ul class="all_dates"></ul>
</div>
and then using jQuery, I wanted to slot every Monday as a <li> into the .monday_dates <ul>, I assume something like $('#start_dates .monday_dates').append()
And then put a complete list of all dates as a <li> into the .all_dates <ul>, I assume something like $('#all_dates .all_dates').append()
So the HTML source would look something like
<div id="start_dates">
<ul class="monday_dates">
<li class="mon">01/02/2021</li>
<li class="mon">08/02/2021</li>
<li class="mon">15/02/2021</li>
<li class="mon">22/02/2021</li>
</ul>
</div>
<div id="all_dates">
<ul class="all_dates">
<li class="day">01/02/2021</li>
<li class="day">02/02/2021</li>
<li class="day">03/02/2021</li>
...
<li class="day">26/02/2021</li>
<li class="day">27/02/2021</li>
<li class="day">28/02/2021</li>
</ul>
</div>
Can anyone help? Or advise.
Thank you, I appreciate your time very much
.getDay return 1 for monday and respectively for other days
<div id="start_dates"></div>
elmRef = document.querySelector("#start_dates");
ulRef = document.createElement("ul");
for (i = 0; i < dates_array.length; i++) {
if (dates_array[i].getDay() == 1) {
li = document.createElement("li");
li.append(dates_array[i].toLocaleString());
ulRef.append(li)
}
}
elmRef.append(ulRef);
You can generate all dates of a month using a while loop and add only dates whose getDay() value is 1 as monday dates.
Then using append() you can add to your html.
const getDaysInMonth = (month, year) => {
const date = new Date(year, month, 1);
const days = [];
const mondays = [];
while (date.getMonth() === month) {
const dateString = new Date(date).toLocaleDateString('en-GB')
if(date.getDay() === 1) {
mondays.push(dateString);
}
days.push(dateString);
date.setDate(date.getDate() + 1);
}
return {days, mondays};
}
const {days, mondays} = getDaysInMonth(1, 2021);
const allMonday = mondays.map(monday => `<li class="mon">${monday}</li>`).join('');
const allDays = days.map(day => `<li class="day">${day}</li>`).join('');
$('#start_dates .monday_dates').append(allMonday);
$('#all_dates .all_dates').append(allDays);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Only Mondays:
<div id="start_dates">
<ul class="monday_dates"></ul>
</div>
All Days:
<div id="all_dates">
<ul class="all_dates"></ul>
</div>

Changing values with jQuery

I have the following:
<span class="label-info">3</span>
I have the following jquery
var replaceit = $(this).closest(':has(.label-info)').find('.label-info').text();
The value of the variable is always a single whole number but will not always be 3:
ie: 1, 2, 3, 4, 5.
I have tried this numerous ways and cannot get the value to change. My latest attempt was:
return $(this).closest(':has(.label-info)').html().replace(replaceit, (replaceit - 1));
My end result, is to subtract 1 from whatever the current value of "lable-info" is, and switch it with this new result. So a new span based on the value of 3 would become.
<span class="label-info">2</span>
How do I achieve this?
Updated Code for more clarity
html:
<div>
<span class="lable-info">3</span>
</div>
<div>
<a class="accept_friend">accept</a>
</div>
javascript:
$(document).on("click", "a.accept_friend", function() {
var checkValue = $(this).closest(':has(.name)').find('.name').text();
var removeit = $(this).closest(':has(.item)').find('.item').fadeOut();
var replaceit = $(this).closest(':has(.label-info)').find('.label-info').text();
$.ajax({
url: '/includes/accept_friend.php',
type: 'post',
data: {checkValue},
success:function(data){
return removeit;
$("a.remove_pending").text(function () {
return ('.label-info').html().replace(replacei, replaceit);
});
}
Notes:
I am not using id. I am using class. There are multiple classes with the same name. So I have to call by closest.
Getting a value from a span, subtracting it by 1 and updating the span(using jQuery):
HTML
<span class="label-info">3</span>
jQuery
var n = $(".label-info").text(),
n2 = n - 1;
$(".label-info").text(n2);
Hope it helps a bit
Please try below code
var currentVal = $(this).closest(':has(.label-info)').html();
var newValue = parseInt(currentVal - 1);
return newValue;
Hope this helps you
var replaceit = $(this).closest(':has(.label-info)').text();
$(this).closest(':has(.label-info)').text(replaceit-1);
Example fiddle https://jsfiddle.net/nzdtnoas/
You can use .text( function ) to changing text of element to another string.
$(".label-info").text(function(i, text){
return text - 1;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="label-info">3</span>

Get attribute of all list items and add them to input

I have a list like this:
<ul class="draggable">
<li data-bullet="1"> item 1</li>
<li data-bullet="2"> item 2</li>
<li data-bullet="3"> item 3</li>
</ul>
Using javascript, how do I grab all the list item attributes data-bullet and insert them into the value of an input (separated by a comma):
<input id="insertme" type="hidden" name="bullet" value="">
So the end result will be:
<input id="insertme" type="hidden" name="bullet" value="1,2,3">
I know how to get individual list items but can't get my head around how to get them all and insert them there.
Here you go, A pure javascript solution
Try to use dataset at this context,
var res = "";
[].forEach.bind(document.querySelectorAll(
'.draggable > li[data-bullet]'),function(itm, i){
res += ((i) ? ":" : "") + itm.dataset.bullet;
})();
document.getElementById("insertme").value = res;
DEMO
Or the less complex and a readable version would be,
var elemArray = Array.from(document.querySelectorAll('.draggable > li[data-bullet]')),
res ="";
elemArray.forEach(function(){
res += ((i) ? ":" : "") + itm.dataset.bullet;
});
document.getElementById("insertme").value = res;
As per your new requirement, you can accomplish your task by,
$("button").click(function() {
var parent = $(this).parent();
parent.closest(".draggable").next(":text").val(parent.siblings("li").addBack().map(function(){
return $(this).data("bullet")
}).get().join(":"));
});
DEMO
try
var allBullets = [];
$(".draggable li").each(function(){
allBullets.push($(this).attr("data-bullet"));
});
$("#insertme").val(allBullets.join(","));
If you can use querySelectorAll to find elements and then map it using getAttribute method. For example (ES6 syntax):
const items = document.querySelectorAll('.draggable li');
const result = [...items].map(el => el.getAttribute('data-bullet')).join();
document.getElementById('insertme').value = result;
ES5 analogy:
var items = document.querySelectorAll('.draggable li');
var result = [].slice.call(items).map(function(el) {
return el.getAttribute('data-bullet');
}).join();
document.getElementById('insertme').value = result;

jQuery script for finding elements by typing and organize them

I would like to search by any term (name, user, from, price), and display the div into top and hide the ones who doesn't have the typed value.
Here's the jsfiddle: http://jsfiddle.net/Sc9ys/10/
I would like to have the same result as the jquery mobile table filter http://demos.jquerymobile.com/1.4.0/filterable/
Where you can search for any term.
I know that for search for any term I should use $(list).find("li *:)... but I can't figure out how to display the items properly. If you test my jsfiddle it doesn't work very well.
Edit: As asked by the user below, here's some more info.
<ul id='list'>
<li>
<div class='row'>
<div class='middle'>
<ul>
<li><h3>Stackoverflow</h3></li>
<li><span>User</span></li>
<li><span>London</span></li>
</ul>
</div>
<div style='clear: both'></div>
</div>
</li>
</ul>
$("#search").change( function () {
$(list).find("li *:not(:Contains(" + filter + "))").parent().hide();
});
DEMO
The idea is in
$("#ul_container").find("li").filter(function () {//your comparing logic here });
Here, try this out. Honesty I couldn't read thru your code, so I made this example. I added the sub items (spans that contain data to be searched) in an array datalist by their class name.
Generic Search Function.
HTML
<input type="text" id="search" />
<ul id="ul_container">
<li class="listItem">
<span class="car">Honda</span>
<span class="country">Japan</span>
</li>
<li class="listItem">
<span class="car">BMW</span>
<span class="country">Germany</span>
</li>
</ul>
Script:
//Capture user input
$("#search").on("keyup change", function () {
var str = $.trim($(this).val());
if (str) {
search(str);
} else {
// if no input, then show all
$(".listItem").show();
}
});
//the search part.
var datalist = ["car", "country"];
function search(toFind) {
//select all li and loop thru them one by one
$("#ul_container").find("li").filter(function () {
var $li = $(this);//hold current li in a variable
//loop thru all sub spans by their class and check if the toFind keyword is there
// you modify this step, i use it to specify which sub span to be searched. Sometimes I don't want all field to be searched, only the ones I select.
for (var i = 0; i < datalist.length; i++) {
//hold the span in a var called $item
var $item = $li.children("." + datalist[i]);
var content_str = $item.html();//get the actual string
//the comparing code
if (content_str.toLowerCase().indexOf(toFind.toLowerCase()) >= 0) {
$li.show();
break;
} else {
$li.hide();
}
}
});
}
Solved guys. Thank you all.
You can see the following example working at: http://jsfiddle.net/Sc9ys/29/
$('#search').on('keyup change', function(){
var str = $.trim($(this).val());
if (str) {
search(str, $("#list"));
} else {
$("#list").find('li').show();
/* The <li> are display: none, to show them again if the input type is clear,
we must find those <li> and show them. Showing only the #list isn't enough. */
}
});
function search(toFind, list){
$(list).find('li').filter(function() {
$li = $(this);
$li.find(".middle :contains(" + toFind +")").parent().parent().slideDown();
$li.find(".middle").not(":contains(" + toFind + ")").parent().parent().slideUp();
});
}
/* Function to search with the input lowercase */
$.expr[":"].contains = $.expr.createPseudo(function(arg) {
return function( elem ) {
return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
};
});
Edit: Made some adjustments according to the help of user #Joraid.

Categories

Resources