Bootstrap DatePicker on Safari / Angular - html

i need some help with the safari browser. I have a angular app which have a function to select on ngOnInit the current week in a datepicken.
It works fine with firefox, brave, chrome and so on.
but it doesn't work on safari.
i don't know how to solve it. and the google search doesn't help me anyway. some say that it doesn't work on safari but not how i can solve it.
as already mentioned, i need a datepicker that automatically selects the current week. because i have to save the week number + year ("22/2022") in the database. but i also want to be able to select the next weeks.
ts page
ngOnInit(): void {
this.onDateSelection(this.calendar.getToday());
}
getWeekNumber(from: NgbDate) {
let currentDate = new Date(from.year, from.month, from.day);
var oneJan = new Date(currentDate.getFullYear(), 0, 1);
var numberOfDays = Math.floor(
(Number(currentDate) - Number(oneJan)) / (24 * 60 * 60 * 1000)
);
return Math.ceil((currentDate.getDay() + 1 + numberOfDays) / 7);
}
onDateSelection(date: NgbDate) {
let fromDate = new Date(date.year + "-" + date.month + "-" + date.day);
let time = fromDate.getDay() ? fromDate.getDay() - 1 : 6;
fromDate = new Date(fromDate.getTime() - time * 24 * 60 * 60 * 1000);
this.fromDate = new NgbDate(
fromDate.getFullYear(),
fromDate.getMonth() + 1,
fromDate.getDate()
);
const toDate = new Date(fromDate.getTime() + 6 * 24 * 60 * 60 * 1000);
this.toDate = new NgbDate(
toDate.getFullYear(),
toDate.getMonth() + 1,
toDate.getDate()
);
this.currentDate = `${
this.fromDate.day < 10 ? "0" + this.fromDate.day : this.fromDate.day
}.${
this.fromDate.month < 10 ? "0" + this.fromDate.month : this.fromDate.month
}. - ${this.toDate.day < 10 ? "0" + this.toDate.day : this.toDate.day}.${
this.toDate.month < 10 ? "0" + this.toDate.month : this.toDate.month
}.${this.toDate.year}`;
}
isHovered(date: NgbDate) {
return (
this.fromDate &&
!this.toDate &&
this.hoveredDate &&
date.after(this.fromDate) &&
date.before(this.hoveredDate)
);
}
isInside(date: NgbDate) {
return this.toDate && date.after(this.fromDate) && date.before(this.toDate);
}
isRange(date: NgbDate) {
return (
date.equals(this.fromDate) ||
(this.toDate && date.equals(this.toDate)) ||
this.isInside(date) ||
this.isHovered(date)
);
}
html page

safari has too much date format regex. you have to replace like that. for example
getWeekNumber(from: NgbDate) {
let currentDate = new Date(from.year.replace(/-/g, "/"), from.month.replace(/-/g, "/"), from.day.replace(/-/g, "/"));
...
}

had just to modify the new Date() to
onDateSelection(date: NgbDate) {
let fromDate = new Date(date.year, date.month - 1, date.day);
...
}

Related

Create one time popup with materialize css

Is there any way to evade jquery and make notification be shown only one time per browser ?
For example, goes to website, notification pops up and that is it, next time when user comes to site from same browser notification wont be showen to him.
I would mainly try to evade adding jquery just for that, so if anyone knows a way to do this with materializecss or some plain html i would be thankful.
How do you trigger the notification?
You could do a basic localStorage check for example to "detect" if the notification has been displayed or not:
function foo() {
const hasSeenNotification = window.localStorage.getItem('shown');
if (!hasSeenNotification) {
window.localStorage.setItem('shown', true);
// show notification here
// ...
}
}
You need to add cookies.
And then check is it is exists:
if (GetCookieShowMessageDocument('ShowPoPUP'))
{
...
}
Here is a sample:
function GetCookieShowMessageDocument(c_name) {
var i, x, y, ARRcookies = document.cookie.split(";");
for (i = 0; i < ARRcookies.length; i++) {
x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
x = x.replace(/^\s+|\s+$/g, "");
if (x == c_name) {
return unescape(y);
}
}
}
function SetCookieShowMessageDocument(name, value, days) {
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
}
else var expires = "";
document.cookie = name + "=" + escape(value) + expires + "; path=/";
}

How to implement duration picker with HTML5 or/with Angular8, with hours more than 24?

I am trying to implement a control, using either
<input type="time"/>
or just with
<input type="text"/>
and implement a duration picker control which can have hours format more than 24, something like 000:00:00 or hhh:mm:ss, and no am/pm option ( The default input type for time has formats in am/pm format, which is not useful in my case).
The requirement is to be able to increase decrease the duration using up and down keys much like the default input type time of HTML.
Is there any native HTML, angular, or material component for this?
Or is there a way to achieve this using regular expression/patterns or something?
One way I can think of is to write your custom control (as also mentioned by #Allabakash). For Native HTML, The control can be something like this:
window.addEventListener('DOMContentLoaded', (event) => {
document.querySelectorAll('[my-duration-picker]').forEach(picker => {
//prevent unsupported keys
const acceptedKeys = ['Backspace', 'ArrowLeft', 'ArrowRight', 'ArrowDown', 'ArrowUp'];
const selectFocus = event => {
//get cursor position and select nearest block;
const cursorPosition = event.target.selectionStart;
"000:00:00" //this is the format used to determine cursor location
const hourMarker = event.target.value.indexOf(":");
const minuteMarker = event.target.value.lastIndexOf(":");
if (hourMarker < 0 || minuteMarker < 0) {
//something wrong with the format. just return;
return;
}
if (cursorPosition < hourMarker) {
event.target.selectionStart = 0; //hours mode
event.target.selectionEnd = hourMarker;
}
if (cursorPosition > hourMarker && cursorPosition < minuteMarker) {
event.target.selectionStart = hourMarker + 1; //minutes mode
event.target.selectionEnd = minuteMarker;
}
if (cursorPosition > minuteMarker) {
event.target.selectionStart = minuteMarker + 1; //seconds mode
event.target.selectionEnd = minuteMarker + 3;
}
}
const insertFormatted = (inputBox, secondsValue) => {
let hours = Math.floor(secondsValue / 3600);
secondsValue %= 3600;
let minutes = Math.floor(secondsValue / 60);
let seconds = secondsValue % 60;
minutes = String(minutes).padStart(2, "0");
hours = String(hours).padStart(3, "0");
seconds = String(seconds).padStart(2, "0");
inputBox.value = hours + ":" + minutes + ":" + seconds;
}
const increaseValue = inputBox => {
const rawValue = inputBox.value;
sectioned = rawValue.split(':');
let secondsValue = 0
if (sectioned.length === 3) {
secondsValue = Number(sectioned[2]) + Number(sectioned[1] * 60) + Number(sectioned[0] * 60 * 60);
}
secondsValue += 1;
insertFormatted(inputBox, secondsValue);
}
const decreaseValue = inputBox => {
const rawValue = inputBox.value;
sectioned = rawValue.split(':');
let secondsValue = 0
if (sectioned.length === 3) {
secondsValue = Number(sectioned[2]) + Number(sectioned[1] * 60) + Number(sectioned[0] * 60 * 60);
}
secondsValue -= 1;
if (secondsValue < 0) {
secondsValue = 0;
}
insertFormatted(inputBox, secondsValue);
}
const validateInput = event => {
sectioned = event.target.value.split(':');
if (sectioned.length !== 3) {
event.target.value = "000:00:00"; //fallback to default
return;
}
if (isNaN(sectioned[0])) {
sectioned[0] = "000";
}
if (isNaN(sectioned[1]) || sectioned[1] < 0) {
sectioned[1] = "00";
}
if (sectioned[1] > 59 || sectioned[1].length > 2) {
sectioned[1] = "59";
}
if (isNaN(sectioned[2]) || sectioned[2] < 0) {
sectioned[2] = "00";
}
if (sectioned[2] > 59 || sectioned[2].length > 2) {
sectioned[2] = "59";
}
event.target.value = sectioned.join(":");
}
const controlsDiv = document.createElement("div");
const scrollUpBtn = document.createElement("button");
const scrollDownBtn = document.createElement("button");
scrollDownBtn.textContent = " - ";
scrollUpBtn.textContent = " + ";
scrollUpBtn.addEventListener('click', (e) => {
increaseValue(picker);
});
scrollDownBtn.addEventListener('click', (e) => {
decreaseValue(picker);
});
picker.parentNode.insertBefore(scrollDownBtn, picker.nextSibling);
picker.parentNode.insertBefore(scrollUpBtn, picker.nextSibling);
picker.value = "000:00:00";
picker.style.textAlign = "right"; //align the values to the right (optional)
picker.addEventListener('keydown', event => {
//use arrow keys to increase value;
if (event.key == 'ArrowDown' || event.key == 'ArrowUp') {
if(event.key == 'ArrowDown'){
decreaseValue(event.target);
}
if(event.key == 'ArrowUp'){
increaseValue(event.target);
}
event.preventDefault(); //prevent default
}
if (isNaN(event.key) && !acceptedKeys.includes(event.key)) {
event.preventDefault(); //prevent default
return false;
}
});
picker.addEventListener('focus', selectFocus); //selects a block of hours, minutes etc
picker.addEventListener('click', selectFocus); //selects a block of hours, minutes etc
picker.addEventListener('change', validateInput);
picker.addEventListener('blur', validateInput);
picker.addEventListener('keyup', validateInput);
});
});
<input type="text" my-duration-picker></input>
Tested and working on Google Chrome 78. I will do a Angular version later.
For the Angular version, you can write your own custom Directive and just import it to your app-module-ts declarations. See this example on stackblitz:
App Demo: https://angular-xbkeoc.stackblitz.io
Code: https://stackblitz.com/edit/angular-xbkeoc
UPDATE: I developed and improved this concept over time. You can checkout the picker here 👉 https://nadchif.github.io/html-duration-picker.js/
checkout this solution , https://github.com/FrancescoBorzi/ngx-duration-picker. which provides options you are looking for.
here is the demo - https://embed.plnkr.co/1dAIGrGqbcfrNVqs4WwW/.
Demo shows Y:M:W:D:H:M:S format. you can hide the parameters using flags defined in docs.
Since you are looking for duration picker with single input, creating your own component will be handy.
You can consider the concepts formatters and parsers.
checkout this topics which helps you in achieving that.
https://netbasal.com/angular-formatters-and-parsers-8388e2599a0e
https://stackoverflow.com/questions/39457941/parsers-and-formatters-in-angular2
here is the updated sample demo - https://stackblitz.com/edit/hello-angular-6-yuvffz
you can implement the increase/decrease functionalities using keyup/keydown event functions.
handle(event) {
let value = event.target.value; //hhh:mm:ss
if(event.key === 'ArrowUp') {
console.log('increase');
} else if (event.key === 'ArrowDown') {
console.log('decrease');
} else {
//dont allow user from entering more than two digits in seconds
}
}
Validations you need to consider ::
- If user enters wrong input, show error message / block from entering anything other than numbers
- allowing only unit specific digits - (Ex :: for hr - 3 digits, mm - 2 digits etc as per your requirement)
To do something more interesting or make it look like interactive you can use the
flipclock.js which is very cool in looking and to work with it is also feasible.
Here is the link :-
http://flipclockjs.com/
You can try with number as type :
<input type="min" min="0" max="60">
demo :
https://stackblitz.com/edit/angular-nz9hrn

How to dynamically add mat-icon to divs with angular renderer2?

I have a HTML with a lot of divs. I have already generated divs that look like this.
static HTML (not dynamically generated) example of desired result using renderer2
<div class="time-rowss clearfixx" #timerowss>
<div><mat-icon>today</mat-icon> date </div>
</div>
<div class="time-rows clearfix" #timerows>
<div><mat-icon>brightness_3</mat-icon>00:00</div>
<div><mat-icon>brightness_3</mat-icon>01:00</div>
<div><mat-icon>brightness_3</mat-icon>02:00</div>
</div>
I want to achieve the same but dynamically generating the divs.
What I have done so far is add dynamically times and dates.
Here is my code:
for (let j = this.requestVehicle.startDateTime.getDate(); j < this.requestVehicle.endDateTime.getDate(); j++) {
const newTime = new Date(time.getTime() + 24 * 3600 * 1000);
time = newTime;
const date = this.renderer.createElement('div');
this.renderer.appendChild(date, this.renderer.createText(newTime.getDate() + '/' + newTime.getMonth() + '/' + newTime.getFullYear()));
this.renderer.appendChild(this.d7.nativeElement, date);
for (let i = 0; i < 24; i++) {
const b = this.renderer.createElement('div');
const icon = this.renderer.createElement('mat-icon');
if (i < 7 || i > 18) {
this.renderer.setAttribute(icon, 'svgIcon', '"brightness_3"');
} else {
this.renderer.setProperty(icon, 'svgIcon', '"wb_sunny"');
}
let text;
if (i >= 10) {
text = ' ' + i;
} else {
text = '0' + i;
}
this.renderer.appendChild(b, icon);
this.renderer.appendChild(b, this.renderer.createText(text + ':00'));
this.renderer.appendChild(this.d3.nativeElement, b);
}
}
I have tried several options:
this.renderer.setProperty(icon, 'svgIcon', '"wb_sunny"');
this.renderer.setProperty(icon, 'svgIcon', 'wb_sunny');
this.renderer.setAttribute(icon, 'svgIcon', '"brightness_3"');
this.renderer.setAttribute(icon, 'svgIcon', 'brightness_3');
this.renderer.appendChild(icon, this.renderer.createText('brightness'));
this.renderer.appendChild(icon, 'brightness_3');
none of these options work. I also tried iconName instead of svgIcon.
how should I add iconName or svgIcon with renderer2?
I figured it out. I what I was noticed when I tried to add mat-icon value with renderer createText. It was adding it correctly. The problem was that the IconName was appearing in html as name not as an icon. So I realized the css was missing. I looked into the dev tools and inspected the divs and mat-icons. I found out that they were missing classes.
So I added the classes manually.
In short
you need to create mat-icon element.
const dateIcon = this.renderer.createElement('mat-icon');
add value using createText.
this.renderer.appendChild(dateIcon, this.renderer.createText('today'));
give classes for css styling.
this.renderer.addClass(dateIcon, 'mat-icon');
this.renderer.addClass(dateIcon, 'material-icons');
Full code if curious. -->
for (let j = this.requestVehicle.startDateTime.getDate(); j < this.requestVehicle.endDateTime.getDate(); j++) {
const newTime = new Date(time.getTime() + 24 * 3600 * 1000);
time = newTime;
const date = this.renderer.createElement('div');
const dateIcon = this.renderer.createElement('mat-icon');
this.renderer.appendChild(dateIcon, this.renderer.createText('today'));
this.renderer.addClass(dateIcon, 'mat-icon');
this.renderer.addClass(dateIcon, 'material-icons');
this.renderer.appendChild(date, dateIcon);
this.renderer.appendChild(date, this.renderer.createText(newTime.getDate() + '/' + newTime.getMonth() + '/' + newTime.getFullYear()));
this.renderer.appendChild(this.d7.nativeElement, date);
for (let i = 0; i < 24; i++) {
const b = this.renderer.createElement('div');
const icon = this.renderer.createElement('mat-icon');
if (i < 7 || i > 18) {
this.renderer.appendChild(icon, this.renderer.createText('brightness_3'));
} else {
this.renderer.appendChild(icon, this.renderer.createText('wb_sunny'));
}
let text;
if (i >= 10) {
text = ' ' + i;
} else {
text = '0' + i;
}
this.renderer.appendChild(b, icon);
this.renderer.addClass(icon, 'mat-icon');
this.renderer.addClass(icon, 'material-icons');
this.renderer.appendChild(b, this.renderer.createText(text + ':00'));
this.renderer.appendChild(this.d3.nativeElement, b);
}
}

Funky IE JSON conversions

When running our AngularJS app in IE11 everything looks great in the debugger, but when our app encodes the data as JSON to save to our database, we get bad results.
Our app obtains a record from our database, then some manipulation is done and then the data is saved back to the server from another model.
Here is the data I got back from the server in the setAttendanceGetSInfo() function below:
{"data":{"Start":"2014-10-16T19:36:00Z","End":"2014-10-16T19:37:00Z"},
This is the code used to "convert the data" to 3 properties in our model:
var setAttendanceGetSInfo = function (CourseId, PID) {
return setAttendanceInfo(CourseId, PID)
.then(function (result) {
return $q.all([
$http.get("../api/Axtra/getSInfo/" + model.event.Id),
$http.get("../api/Axtra/GetStartAndEndDateTime/" + aRow.Rid)
]);
}).then(function (result) {
var r = result.data;
var e = Date.fromISO(r.Start);
var f = Date.fromISO(r.End);
angular.extend(model.event, {
examDate: new Date(e).toLocaleDateString(),
examStartTime: (new Date(e)).toLocaleTimeString(),
examEndTime: (new Date(f)).toLocaleTimeString()
});
return result.sInfo;
});
};
fromISO is defined as:
(function(){
var D= new Date('2011-06-02T09:34:29+02:00');
if(!D || +D!== 1307000069000){
Date.fromISO= function(s){
var day, tz,
rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
p= rx.exec(s) || [];
if(p[1]){
day= p[1].split(/\D/);
for(var i= 0, L= day.length; i<L; i++){
day[i]= parseInt(day[i], 10) || 0;
};
day[1]-= 1;
day= new Date(Date.UTC.apply(Date, day));
if(!day.getDate()) return NaN;
if(p[5]){
tz= (parseInt(p[5], 10)*60);
if(p[6]) tz+= parseInt(p[6], 10);
if(p[4]== '+') tz*= -1;
if(tz) day.setUTCMinutes(day.getUTCMinutes()+ tz);
}
return day;
}
return NaN;
}
}
else{
Date.fromISO= function(s){
return new Date(s);
}
}
})()
Take a look at the screenshot of the event model data:
But, if I eval the event model using JSON.stringify(model.event), I get this:
{\"examDate\":\"?10?/?16?/?2014\",\"examStartTime\":\"?2?:?44?:?00? ?PM\",\"examEndTime\":\"?2?:?44?:?00? ?PM\"}
And this is the JSON encoded data that actually got stored on the DB:
"examDate":"¿10¿/¿16¿/¿2014","examStartTime":"¿2¿:¿36¿:¿00¿ ¿PM","examEndTime":"¿2¿:¿37¿:¿00¿ ¿PM"
What is wrong here and how can I fix this? It works exactly as designed in Chrome and Firefox. I have not yet tested on Safari or earlier versions of IE.
The toJSON for the date class isn't defined perfectly the same for all browsers.
(You can see a related question here: Discrepancy in JSON.stringify of date values in different browsers
I would suspect that you have a custom toJSON added to the Date prototype since your date string doesn't match the standard and that is likely where your issue is. Alternatively, you can use the Date toJSON recommended in the above post to solve your issues.
First, I modified the fromISO prototype to this:
(function () {
var D = new Date('2011-06-02T09:34:29+02:00');
if (!D || +D !== 1307000069000) {
Date.fromISO = function (s) {
var D, M = [], hm, min = 0, d2,
Rx = /([\d:]+)(\.\d+)?(Z|(([+\-])(\d\d):(\d\d))?)?$/;
D = s.substring(0, 10).split('-');
if (s.length > 11) {
M = s.substring(11).match(Rx) || [];
if (M[1]) D = D.concat(M[1].split(':'));
if (M[2]) D.push(Math.round(M[2] * 1000));// msec
}
for (var i = 0, L = D.length; i < L; i++) {
D[i] = parseInt(D[i], 10);
}
D[1] -= 1;
while (D.length < 6) D.push(0);
if (M[4]) {
min = parseInt(M[6]) * 60 + parseInt(M[7], 10);// timezone not UTC
if (M[5] == '+') min *= -1;
}
try {
d2 = Date.fromUTCArray(D);
if (min) d2.setUTCMinutes(d2.getUTCMinutes() + min);
}
catch (er) {
// bad input
}
return d2;
}
}
else {
Date.fromISO = function (s) {
return new Date(s);
}
}
Date.fromUTCArray = function (A) {
var D = new Date;
while (A.length < 7) A.push(0);
var T = A.splice(3, A.length);
D.setUTCFullYear.apply(D, A);
D.setUTCHours.apply(D, T);
return D;
}
Date.toJSON = function (key) {
return isFinite(this.valueOf()) ?
this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z' : null;
};
})()
Then I added moment.js and formatted the dates when they get stored:
var SaveAffRow = function () {
// make sure dates on coursedate and event are correct.
var cd = model.a.courseDate;
var ed = model.event.examDate;
var est = model.event.examStartTime;
var eet = model.event.examEndTime;
model.a.courseDate = moment(cd).format("MM/DD/YYYY");
model.event.examDate = moment(ed).format("MM/DD/YYYY");
model.event.examStartTime = moment(est).format("MM/DD/YYYY hh:mm A");
model.event.examEndTime = moment(eet).format("MM/DD/YYYY hh:mm A");
affRow.DocumentsJson = angular.toJson({a: model.a, event: model.event});
var aff = {};
if (affRow.Id != 0)
aff = affRow.$update({ Id: affRow.Id });
else
aff = affRow.$save({ Id: affRow.Id });
return aff;
};
and when they get read (just in case they are messed up already):
var setAttendanceGetSInfo = function (CourseId, PID) {
return setAttendanceInfo(CourseId, PID)
.then(function (result) {
return $q.all([
$http.get("../api/Axtra/getSInfo/" + model.event.Id),
$http.get("../api/Axtra/GetStartAndEndDateTime/" + aRow.Rid)
]);
}).then(function (result) {
var r = result.data;
var e = Date.fromISO(r.Start);
var f = Date.fromISO(r.End);
angular.extend(model.event, {
examDate: moment(e).format("MM/DD/YYYY"),
examStartTime: moment(e).format("MM/DD/YYYY hh:mm A"),
examEndTime: moment(f).format("MM/DD/YYYY hh:mm A")
});
return result.sInfo;
});
};

Twitter timeline using JSON not working anymore

For some reason my Twitter code has stopped working - have Twitter changed their API or something and if so, does anyone know how I can fix my code below?
Thanks for your help,
Osu
JQTWEET = {
// Set twitter username, number of tweets & id/class to append tweets
user: 'myusername',
numTweets: 1,
appendTo: '#tweet',
// core function of jqtweet
loadTweets: function() {
$.ajax({
url: 'http://api.twitter.com/1/statuses/user_timeline.json/',
type: 'GET',
dataType: 'jsonp',
data: {
screen_name: JQTWEET.user,
include_rts: true,
count: JQTWEET.numTweets,
include_entities: true
},
success: function(data, textStatus, xhr) {
var html = '<div class="tweet">TWEET_TEXT<div class="time">AGO</div>';
// append tweets into page
for (var i = 0; i < data.length; i++) {
$(JQTWEET.appendTo).append(
html.replace('TWEET_TEXT', JQTWEET.ify.clean(data[i].text))
.replace(/USER/g, data[i].user.screen_name)
.replace('AGO', JQTWEET.timeAgo(data[i].created_at))
.replace(/ID/g, data[i].id_str)
);
}
}
});
},
/**
* relative time calculator FROM TWITTER
* #param {string} twitter date string returned from Twitter API
* #return {string} relative time like "2 minutes ago"
*/
timeAgo: function(dateString) {
var rightNow = new Date();
var then = new Date(dateString);
if ($.browser.msie) {
// IE can't parse these crazy Ruby dates
then = Date.parse(dateString.replace(/( \+)/, ' UTC$1'));
}
var diff = rightNow - then;
var second = 1000,
minute = second * 60,
hour = minute * 60,
day = hour * 24,
week = day * 7;
if (isNaN(diff) || diff < 0) {
return ""; // return blank string if unknown
}
if (diff < second * 2) {
// within 2 seconds
return "right now";
}
if (diff < minute) {
return Math.floor(diff / second) + " seconds ago";
}
if (diff < minute * 2) {
return "about 1 minute ago";
}
if (diff < hour) {
return Math.floor(diff / minute) + " minutes ago";
}
if (diff < hour * 2) {
return "about 1 hour ago";
}
if (diff < day) {
return Math.floor(diff / hour) + " hours ago";
}
if (diff > day && diff < day * 2) {
return "yesterday";
}
if (diff < day * 365) {
return Math.floor(diff / day) + " days ago";
}
else {
return "over a year ago";
}
}, // timeAgo()
/**
* The Twitalinkahashifyer!
* http://www.dustindiaz.com/basement/ify.html
* Eg:
* ify.clean('your tweet text');
*/
ify: {
link: function(tweet) {
return tweet.replace(/\b(((https*\:\/\/)|www\.)[^\"\']+?)(([!?,.\)]+)?(\s|$))/g, function(link, m1, m2, m3, m4) {
var http = m2.match(/w/) ? 'http://' : '';
return '<a class="twtr-hyperlink" target="_blank" href="' + http + m1 + '">' + ((m1.length > 25) ? m1.substr(0, 24) + '...' : m1) + '</a>' + m4;
});
},
at: function(tweet) {
return tweet.replace(/\B[#ï¼ ]([a-zA-Z0-9_]{1,20})/g, function(m, username) {
return '<a target="_blank" class="twtr-atreply" href="http://twitter.com/intent/user?screen_name=' + username + '">#' + username + '</a>';
});
},
list: function(tweet) {
return tweet.replace(/\B[#ï¼ ]([a-zA-Z0-9_]{1,20}\/\w+)/g, function(m, userlist) {
return '<a target="_blank" class="twtr-atreply" href="http://twitter.com/' + userlist + '">#' + userlist + '</a>';
});
},
hash: function(tweet) {
return tweet.replace(/(^|\s+)#(\w+)/gi, function(m, before, hash) {
return before + '<a target="_blank" class="twtr-hashtag" href="http://twitter.com/search?q=%23' + hash + '">#' + hash + '</a>';
});
},
clean: function(tweet) {
return this.hash(this.at(this.list(this.link(tweet))));
}
} // ify
};
For a Javascript-only solution, without fussing with oAuth authentication, you could check out this script
It looks like your code is referencing version 1 of the API, which has been deprecated. Version 1.1 of the API is what is currently supported.
Check this page in the Twitter API documentation for the correct way to reference the 1.1 version of the call you are using.