Twitter Jquery Widget: Creating invalid URLS - javascript

I have a twitter widget on my website. The only problem is, it is creating invalid URLS for the link when you click on the "about 5 hours ago.."
Example: If you click on a recent tweet it takes you to this link, which is invalid: http://twitter.com/#!/ohshititsjake/statuses/63741419709411330
The correct url is:
http://twitter.com/#!/ohshititsjake/statuses/63741419709411328
Here is the part of the script I believe is the problem:
` function build_url() {
var proto = ('https:' == document.location.protocol ? 'https:' : 'http:');
if (s.list) {
return proto+"//api.twitter.com/1/"+s.username[0]+"/lists/"+s.list+"/statuses.json?per_page="+s.count+"&callback=? ";
} else if (s.query == null && s.username.length == 1) {
return proto+'//api.twitter.com/1/statuses/user_timeline.json?screen_name='+s.username[0]+'&count='+s.count+'&callback=?';
} else {
var query = (s.query || 'from:'+s.username.join(' OR from:'));
return proto+'//search.twitter.com/search.json?&q='+escape(query)+'&rpp='+s.count+'&callback=?';
}
}
`
Here is the full javascript:
(function($) {
$.fn.tweet = function(o){
var s = {
username: ["ohshititsjake"],
list: null,
avatar_size: 20,
count: 3,
intro_text: null,
outro_text: null,
join_text: null,
auto_join_text_default: "I said:<br/>",
auto_join_text_ed: "I",
auto_join_text_ing: "I said:<br/>",
auto_join_text_reply: "I replied to",
auto_join_text_url: "I was looking at",
loading_text: null,
query: null
};
if(o) $.extend(s, o);
$.fn.extend({
linkUrl: function() {
var returning = [];
var regexp = /((ftp|http|https):\/\/(\w+:{0,1}\w*#)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%#!\-\/]))?)/gi;
this.each(function() {
returning.push(this.replace(regexp,"$1"));
});
return $(returning);
},
linkUser: function() {
var returning = [];
var regexp = /[\#]+([A-Za-z0-9-_]+)/gi;
this.each(function() {
returning.push(this.replace(regexp,"#$1"));
});
return $(returning);
},
linkHash: function() {
var returning = [];
var regexp = /(?:^| )[\#]+([A-Za-z0-9-_]+)/gi;
this.each(function() {
returning.push(this.replace(regexp, ' #$1'));
});
return $(returning);
},
capAwesome: function() {
var returning = [];
this.each(function() {
returning.push(this.replace(/\b(awesome)\b/gi, '<span class="awesome">$1</span>'));
});
return $(returning);
},
capEpic: function() {
var returning = [];
this.each(function() {
returning.push(this.replace(/\b(epic)\b/gi, '<span class="epic">$1</span>'));
});
return $(returning);
},
makeHeart: function() {
var returning = [];
this.each(function() {
returning.push(this.replace(/(<)+[3]/gi, "<tt class='heart'>♥</tt>"));
});
return $(returning);
}
});
function parse_date(date_str) {
// The non-search twitter APIs return inconsistently-formatted dates, which Date.parse
// cannot handle in IE. We therefore perform the following transformation:
// "Wed Apr 29 08:53:31 +0000 2009" => "Wed, Apr 29 2009 08:53:31 +0000"
return Date.parse(date_str.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i, '$1,$2$4$3'));
}
function relative_time(time_value) {
var parsed_date = parse_date(time_value);
var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
var pluralize = function (singular, n) {
return '' + n + ' ' + singular + (n == 1 ? '' : 's');
};
if(delta < 60) {
return 'less than a minute ago';
} else if(delta < (60*60)) {
return 'about ' + pluralize("minute", parseInt(delta / 60)) + ' ago';
} else if(delta < (24*60*60)) {
return 'about ' + pluralize("hour", parseInt(delta / 3600)) + ' ago';
} else {
return 'about ' + pluralize("day", parseInt(delta / 86400)) + ' ago';
}
}
function build_url() {
var proto = ('https:' == document.location.protocol ? 'https:' : 'http:');
if (s.list) {
return proto+"//api.twitter.com/1/"+s.username[0]+"/lists/"+s.list+"/statuses.json?per_page="+s.count+"&callback=? ";
} else if (s.query == null && s.username.length == 1) {
return proto+'//api.twitter.com/1/statuses/user_timeline.json?screen_name='+s.username[0]+'&count='+s.count+'&callback=?';
} else {
var query = (s.query || 'from:'+s.username.join(' OR from:'));
return proto+'//search.twitter.com/search.json?&q='+escape(query)+'&rpp='+s.count+'&callback=?';
}
}
return this.each(function(i, widget){
var list = $('<ul class="tweet_list">').appendTo(widget);
var intro = '<p class="tweet_intro">'+s.intro_text+'</p>';
var outro = '<p class="tweet_outro">'+s.outro_text+'</p>';
var loading = $('<p class="loading">'+s.loading_text+'</p>');
if(typeof(s.username) == "string"){
s.username = [s.username];
}
if (s.loading_text) $(widget).append(loading);
$.getJSON(build_url(), function(data){
if (s.loading_text) loading.remove();
if (s.intro_text) list.before(intro);
var tweets = (data.results || data);
$.each(tweets, function(i,item){
// auto join text based on verb tense and content
if (s.join_text == "auto") {
if (item.text.match(/^(#([A-Za-z0-9-_]+)) .*/i)) {
var join_text = s.auto_join_text_reply;
} else if (item.text.match(/(^\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+) .*/i)) {
var join_text = s.auto_join_text_url;
} else if (item.text.match(/^((\w+ed)|just) .*/im)) {
var join_text = s.auto_join_text_ed;
} else if (item.text.match(/^(\w*ing) .*/i)) {
var join_text = s.auto_join_text_ing;
} else {
var join_text = s.auto_join_text_default;
}
} else {
var join_text = s.join_text;
};
var from_user = item.from_user || item.user.screen_name;
var profile_image_url = item.profile_image_url || item.user.profile_image_url;
var join_template = '<span class="tweet_join"> '+join_text+' </span>';
var join = ((s.join_text) ? join_template : ' ');
var avatar_template = '<a class="tweet_avatar" href="http://twitter.com/'+from_user+'"><img src="'+profile_image_url+'" height="'+s.avatar_size+'" width="'+s.avatar_size+'" alt="'+from_user+'\'s avatar" title="'+from_user+'\'s avatar" border="0"/></a>';
var avatar = (s.avatar_size ? avatar_template : '');
var date = '<span class="tweet_time">'+relative_time(item.created_at)+'</span>';
var text = '<span class="tweet_text">' +$([item.text]).linkUrl().linkUser().linkHash().makeHeart().capAwesome().capEpic()[0]+ '</span>';
// until we create a template option, arrange the items below to alter a tweet's display.
list.append('<li>' + avatar + date + join + text + '</li>');
list.children('li:first').addClass('tweet_first');
list.children('li:odd').addClass('tweet_even');
list.children('li:even').addClass('tweet_odd');
});
if (s.outro_text) list.after(outro);
$(widget).trigger("loaded").trigger((tweets.length == 0 ? "empty" : "full"));
});
});
};
})(jQuery);

Looking at the permalink's IDs on that user account, they don't match with the IDs getting generated in your post. The answer is probably in this post:
Why a wrong tweet id is returned from twitter API?
so try changing this line:
var date = '<span class="tweet_time">'+relative_time(item.created_at)+'</span>';
to this:
var date = '<span class="tweet_time">'+relative_time(item.created_at)+'</span>';
Really, it's just changing item.id to item.id_str.in the middle of that line.

Related

Loading two similar scripts twice dosn't work

i have this javascript that I called cookiebar.js, it shows a sticky bar message for cookies, (source code)
(function (context) {
"use strict";
var win = context,
doc = win.document;
var global_instance_name = "cbinstance";
function contentLoaded(win, fn) {
var done = false,
top = true,
doc = win.document,
root = doc.documentElement,
add = doc.addEventListener ? "addEventListener" : "attachEvent",
rem = doc.addEventListener ? "removeEventListener" : "detachEvent",
pre = doc.addEventListener ? "" : "on",
init = function (e) {
if (e.type == "readystatechange" && doc.readyState != "complete") return;
(e.type == "load" ? win : doc)[rem](pre + e.type, init, false);
if (!done && (done = true)) fn.call(win, e.type || e);
},
poll = function () {
try {
root.doScroll("left");
} catch (e) {
setTimeout(poll, 50);
return;
}
init("poll");
};
if (doc.readyState == "complete") fn.call(win, "lazy");
else {
if (doc.createEventObject && root.doScroll) {
try {
top = !win.frameElement;
} catch (e) {}
if (top) poll();
}
doc[add](pre + "DOMContentLoaded", init, false);
doc[add](pre + "readystatechange", init, false);
win[add](pre + "load", init, false);
}
}
var Cookies = {
get: function (key) {
return decodeURIComponent(doc.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
},
set: function (key, val, end, path, domain, secure) {
if (!key || /^(?:expires|max\-age|path|domain|secure)$/i.test(key)) {
return false;
}
var expires = "";
if (end) {
switch (end.constructor) {
case Number:
expires = end === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + end;
break;
case String:
expires = "; expires=" + end;
break;
case Date:
expires = "; expires=" + end.toUTCString();
break;
}
}
doc.cookie = encodeURIComponent(key) + "=" + encodeURIComponent(val) + expires + (domain ? "; domain=" + domain : "") + (path ? "; path=" + path : "") + (secure ? "; secure" : "");
return true;
},
has: function (key) {
return new RegExp("(?:^|;\\s*)" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=").test(doc.cookie);
},
remove: function (key, path, domain) {
if (!key || !this.has(key)) {
return false;
}
doc.cookie = encodeURIComponent(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (domain ? "; domain=" + domain : "") + (path ? "; path=" + path : "");
return true;
},
};
var Utils = {
merge: function () {
var obj = {},
i = 0,
al = arguments.length,
key;
if (0 === al) {
return obj;
}
for (; i < al; i++) {
for (key in arguments[i]) {
if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
obj[key] = arguments[i][key];
}
}
}
return obj;
},
str2bool: function (str) {
str = "" + str;
switch (str.toLowerCase()) {
case "false":
case "no":
case "0":
case "":
return false;
default:
return true;
}
},
fade_in: function (el) {
if (el.style.opacity < 1) {
el.style.opacity = (parseFloat(el.style.opacity) + 0.05).toFixed(2);
win.setTimeout(function () {
Utils.fade_in(el);
}, 50);
}
},
get_data_attribs: function (script) {
var data = {};
if (Object.prototype.hasOwnProperty.call(script, "dataset")) {
data = script.dataset;
} else {
var attribs = script.attributes;
var key;
for (key in attribs) {
if (Object.prototype.hasOwnProperty.call(attribs, key)) {
var attr = attribs[key];
if (/^data-/.test(attr.name)) {
var camelized = Utils.camelize(attr.name.substr(5));
data[camelized] = attr.value;
}
}
}
}
return data;
},
normalize_keys: function (options_object) {
var camelized = {};
for (var key in options_object) {
if (Object.prototype.hasOwnProperty.call(options_object, key)) {
var camelized_key = Utils.camelize(key);
camelized[camelized_key] = options_object[camelized_key] ? options_object[camelized_key] : options_object[key];
}
}
return camelized;
},
camelize: function (str) {
var separator = "-",
match = str.indexOf(separator);
while (match != -1) {
var last = match === str.length - 1,
next = last ? "" : str[match + 1],
upnext = next.toUpperCase(),
sep_substr = last ? separator : separator + next;
str = str.replace(sep_substr, upnext);
match = str.indexOf(separator);
}
return str;
},
find_script_by_id: function (id) {
var scripts = doc.getElementsByTagName("script");
for (var i = 0, l = scripts.length; i < l; i++) {
if (id === scripts[i].id) {
return scripts[i];
}
}
return null;
},
};
var script_el_invoker = Utils.find_script_by_id("cookiebanner");
var Cookiebanner = (context.Cookiebanner = function (opts) {
this.init(opts);
});
Cookiebanner.prototype = {
cookiejar: Cookies,
init: function (opts) {
this.inserted = false;
this.closed = false;
this.test_mode = false;
var default_text = "This site uses cookies.";
var default_link = "Detail";
this.default_options = {
cookie: "cookiebanner-accepted",
closeText: "✖",
cookiePath: "/",
debug: false,
expires: Infinity,
zindex: 255,
mask: false,
maskOpacity: 0.5,
maskBackground: "#000",
height: "auto",
minHeight: "21px",
bg: "#000",
fg: "#ddd",
link: "#aaa",
position: "bottom",
message: default_text,
linkmsg: default_link,
moreinfo: "http://www.examplesite123.com/cookie-policy/",
effect: null,
fontSize: "14px",
fontFamily: "arial, sans-serif",
instance: global_instance_name,
textAlign: "center",
acceptOnScroll: true,
};
this.options = this.default_options;
this.script_el = script_el_invoker;
if (this.script_el) {
var data_options = Utils.get_data_attribs(this.script_el);
this.options = Utils.merge(this.options, data_options);
}
if (opts) {
opts = Utils.normalize_keys(opts);
this.options = Utils.merge(this.options, opts);
}
global_instance_name = this.options.instance;
this.options.zindex = parseInt(this.options.zindex, 10);
this.options.mask = Utils.str2bool(this.options.mask);
if ("string" === typeof this.options.expires) {
if ("function" === typeof context[this.options.expires]) {
this.options.expires = context[this.options.expires];
}
}
if ("function" === typeof this.options.expires) {
this.options.expires = this.options.expires();
}
if (this.script_el) {
this.run();
}
},
log: function () {
if ("undefined" !== typeof console) {
console.log.apply(console, arguments);
}
},
run: function () {
if (!this.agreed()) {
var self = this;
contentLoaded(win, function () {
self.insert();
});
}
},
build_viewport_mask: function () {
var mask = null;
if (true === this.options.mask) {
var mask_opacity = this.options.maskOpacity;
var bg = this.options.maskBackground;
var mask_markup =
'<div id="cookiebanner-mask" style="' +
"position:fixed;top:0;left:0;width:100%;height:100%;" +
"background:" +
bg +
";zoom:1;filter:alpha(opacity=" +
mask_opacity * 100 +
");opacity:" +
mask_opacity +
";" +
"z-index:" +
this.options.zindex +
';"></div>';
var el = doc.createElement("div");
el.innerHTML = mask_markup;
mask = el.firstChild;
}
return mask;
},
agree: function () {
this.cookiejar.set(this.options.cookie, 1, this.options.expires, this.options.cookiePath);
return true;
},
agreed: function () {
return this.cookiejar.has(this.options.cookie);
},
close: function () {
if (this.inserted) {
if (!this.closed) {
if (this.element) {
this.element.parentNode.removeChild(this.element);
}
if (this.element_mask) {
this.element_mask.parentNode.removeChild(this.element_mask);
}
this.closed = true;
}
}
return this.closed;
},
agree_and_close: function () {
this.agree();
return this.close();
},
cleanup: function () {
this.close();
return this.unload();
},
unload: function () {
if (this.script_el) {
this.script_el.parentNode.removeChild(this.script_el);
}
context[global_instance_name] = undefined;
return true;
},
insert: function () {
this.element_mask = this.build_viewport_mask();
var zidx = this.options.zindex;
if (this.element_mask) {
zidx += 1;
}
var el = doc.createElement("div");
el.className = "cookiebanner";
el.style.position = "fixed";
el.style.left = 0;
el.style.right = 0;
el.style.height = this.options.height;
el.style.minHeight = this.options.minHeight;
el.style.zIndex = zidx;
el.style.background = this.options.bg;
el.style.color = this.options.fg;
el.style.lineHeight = el.style.minHeight;
el.style.padding = "5px 16px";
el.style.fontFamily = this.options.fontFamily;
el.style.fontSize = this.options.fontSize;
el.style.textAlign = this.options.textAlign;
if ("top" === this.options.position) {
el.style.top = 0;
} else {
el.style.bottom = 0;
}
el.innerHTML = '<div class="cookiebanner-close" style="float:right;padding-left:5px;">' + this.options.closeText + "</div>" + "<span>" + this.options.message + " <a>" + this.options.linkmsg + "</a></span>";
this.element = el;
var el_a = el.getElementsByTagName("a")[0];
el_a.href = this.options.moreinfo;
el_a.target = "_blank";
el_a.style.textDecoration = "none";
el_a.style.color = this.options.link;
var el_x = el.getElementsByTagName("div")[0];
el_x.style.cursor = "pointer";
function on(el, ev, fn) {
var add = el.addEventListener ? "addEventListener" : "attachEvent",
pre = el.addEventListener ? "" : "on";
el[add](pre + ev, fn, false);
}
var self = this;
on(el_x, "click", function () {
self.agree_and_close();
});
if (this.element_mask) {
on(this.element_mask, "click", function () {
self.agree_and_close();
});
doc.body.appendChild(this.element_mask);
}
if (this.options.acceptOnScroll) {
on(window, "scroll", function () {
self.agree_and_close();
});
}
doc.body.appendChild(this.element);
this.inserted = true;
if ("fade" === this.options.effect) {
this.element.style.opacity = 0;
Utils.fade_in(this.element);
} else {
this.element.style.opacity = 1;
}
},
};
if (script_el_invoker) {
if (!context[global_instance_name]) {
context[global_instance_name] = new Cookiebanner();
}
}
})(window);
I load it in this way in functions.php in Wordpress:
function wpb_hook_javascript() {
?>
<script defer type="text/javascript" id="cookiebanner" src="https://www.examplesite123.com/cookiebar.js"></script>
<?php
}
add_action('wp_head', 'wpb_hook_javascript');
It works fine.
Now i duplicate the same javascript code and i called it stickybar.js. I add some modifications, also change class with name "stickybar":
The code of the stickybar.js is here (i pasted it in jsfiddle because there is too much text for stackoverflow)
Then i show this second bar (stickybar.js) only on mobile device and after 8 second with this CSS:
.stickybar { display: none; }
#media only screen and (max-device-width:480px) {
.stickybar {
display: block;
animation: cssAnimation 0s 8s forwards;
visibility: hidden;
}
#keyframes cssAnimation {
to { visibility: visible; }
}
}
I load it in Wordpress with this code in functions.php:
function wpb_hook_javascript() {
?>
<script defer type="text/javascript" id="cookiebanner" src="https://www.examplesite123.com/stickybar.js"></script>
<?php
}
add_action('wp_head', 'wpb_hook_javascript');
It works fine.
If i load one by one of this codes, they work fine.
The problem is that when i load the two scripts together in this way in functions.php, only the first works:
function wpb_hook_javascript() {
?>
<script defer type="text/javascript" id="cookiebanner" src="https://www.examplesite123.com/cookiebar.js"></script>
<script defer type="text/javascript" id="cookiebanner" src="https://www.examplesite123.com/stickybar.js"></script>
<?php
}
add_action('wp_head', 'wpb_hook_javascript');
How can i load the two scripts together?
The comment thread on this question is semantically correct, you can only have one instance of each html id attribute, they must be unique, and your find_script_by_id methods are both searching for the same thing.
However, you're doing what's generally called "baking in" the scripts into your header which is at best, a faux pas, at least as far as WordPress is concerned. Properly Enqueueing Scripts (and styles) is very easy in WordPress, and your future self, web clients, and other people who look at your code will thank you for doing it.
It's not unlike how you're "baking in" the scripts now:
function wpb_hook_javascript() {
?>
<script defer type="text/javascript" id="cookiebanner" src="https://www.examplesite123.com/cookiebar.js"></script>
<script defer type="text/javascript" id="cookiebanner" src="https://www.examplesite123.com/stickybar.js"></script>
<?php
}
add_action('wp_head', 'wpb_hook_javascript');
But with a few things changed:
function enqueue_my_scripts(){
wp_enqueue_script( 'cookie-bar', 'https://www.examplesite123.com/cookiebar.js', array(), '1.0', true );
wp_enqueue_script( 'sticky-bar', 'https://www.examplesite123.com/stickybar.js', array(), '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'enqueue_my_scripts' );
Namely, it uses the wp_enqueue_script() function on the wp_enqueue_scripts hook. This lets you defer the script to the footer, load in the header, add version numbers to prevent caching issues, add dependencies, allows you to dynamically add/remove them programatically,gives them unique ID's based on the handle, and much more. (You do still need to update your find_script_by_id functions to use these new handles instead cookie-bar, sticky-bar, change the global_instance_name, etc. (more on that in a second)
With that said, if the .js files are on your server, you'll want to use site_url(), plugins_url(), get_stylesheet_directory_uri(), or similar functions to grab the URL of the file instead of typing it out. If you're using a remote resource, don't worry about it, but if they're on you're site, you should swap out the baked in version for that so you don't have issues if you ever move your site, and it allows you easier methods to edit the version to prevent caching problems if you change them.
Back to your variables, you may also want to replace your find_script_by_id type functions with document.currentScript instead, to allow them to be more abstract and not rely on typo/duplicate prone element IDs, and instead reference the currently running <script> tag.

js for newest chat message order

in my chat extension for phpBB, i use ajax for the js with a little jquery mixed in. i'm setting it up for users to select if they want the newest messages at the top or the bottom in accordance to their setting in their user control panel. the php side of it is done and works well but the js is still adding the new message at the top, ignoring the sort order in the php.
in the php. note that the sort order is set with this line
ORDER BY c.message_id ' . ($this->user->data['user_ajax_chat_messages_down'] ? 'DESC' : 'ASC');
i can't post the php in this post as the body is limited to 30000 characters. so i will post it if needed.
here is the js that does all the work
function setCookie(name, value, expires, path, domain, secure) {
var today = new Date();
today.setTime(today.getTime());
if (expires) {
expires = expires * 1000 * 60 * 60 * 24;
}
var expires_date = new Date(today.getTime() + (expires));
document.cookie = name + '=' + escape(value) +
((expires) ? ';expires=' + expires_date.toGMTString() : '') + //expires.toGMTString()
((path) ? ';path=' + path : '') +
((domain) ? ';domain=' + domain : '') +
((secure) ? ';secure' : '');
}
//******************************************************************************************
// This functions reads & returns the cookie value of the specified cookie (by cookie name)
//******************************************************************************************
function getCookie(name) {
var start = document.cookie.indexOf(name + "=");
var len = start + name.length + 1;
if ((!start) && (name !== document.cookie.substring(0, name.length))) {
return null;
}
if (start === -1)
return null;
var end = document.cookie.indexOf(';', len);
if (end === -1)
end = document.cookie.length;
return unescape(document.cookie.substring(len, end));
}
function deletecookie(name)
{
var cookie_date = new Date( ); // current date & time
cookie_date.setTime(cookie_date.getTime() - 1);
document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString();
location.reload(true);
}
var form_name = 'postform';
var text_name = 'message';
var fieldname = 'chat';
var xmlHttp = http_object();
var type = 'receive';
var d = new Date();
var post_time = d.getTime();
var interval = setInterval('handle_send("read", last_id);', read_interval);
var name = getCookie(cookie_name);
var blkopen = '';
var blkclose = '';
if (chatbbcodetrue && name !== null && name !== 'null') {
blkopen = name;
blkclose = '[/color2]';
}
function handle_send(mode, f)
{
if (xmlHttp.readyState === 4 || xmlHttp.readyState === 0)
{
indicator_switch('on');
type = 'receive';
param = 'mode=' + mode;
param += '&last_id=' + last_id;
param += '&last_time=' + last_time;
param += '&last_post=' + post_time;
param += '&read_interval=' + read_interval;
if (mode === 'add' && document.postform.message.value !== '')
{
type = 'send';
for (var i = 0; i < f.elements.length; i++)
{
elem = f.elements[i];
param += '&' + elem.name + '=' + blkopen + "" + encodeURIComponent(elem.value) + blkclose;
}
document.postform.message.value = '';
} else if (mode === 'add' && document.postform.message.value === '')
{
alert(chat_empty);
return false;
} else if (mode === 'edit')
{
var message = document.getElementById('message').value;
type = 'edit';
mode += '/' + f;
param = '&submit=1&message=' + message;
} else if (mode === 'delete')
{
var parent = document.getElementById('chat');
var child = document.getElementById('p' + f);
parent.removeChild(child);
type = 'delete';
param += '&chat_id=' + f;
} else if (mode === 'quotemessage')
{
type = 'quotemessage';
param += '&chat_id=' + f;
}
xmlHttp.open('POST', query_url + '/' + mode, true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttp.onreadystatechange = handle_return;
xmlHttp.send(param);
}
}
function handle_return()
{
if (xmlHttp.readyState === 4)
{
if (xmlHttp.status == 200)
{
results = xmlHttp.responseText.split('--!--');
if (type === 'quotemessage') {
if (results[0]) {
$text = document.getElementById('message').value;
document.getElementById('message').value = $text + results[0];
document.getElementById("message").focus();
$('#chat').find('.username, .username-coloured').attr('title', chat_username_title);
}
} else if (type === 'edit') {
jQuery(function($) {
'use strict';
var opener = window.opener;
if (opener) {
$(opener.document).find('#p' + last_id).replaceWith(results[0]);
}
var popup = window.self;
popup.opener = window.self;
popup.close();
$('#chat').find('.username, .username-coloured').attr('title', chat_username_title);
});
} else if (type !== 'delete') {
if (results[1])
{
if (last_id === 0)
{
document.getElementById(fieldname).innerHTML = results[0];
} else
{
document.getElementById(fieldname).innerHTML = results[0] + document.getElementById(fieldname).innerHTML;
}
last_id = results[1];
if (results[2])
{
document.getElementById('whois_online').innerHTML = results[2];
last_time = results[3];
if (results[4] !== read_interval)
{
read_interval = results[4];
window.clearInterval(interval);
interval = setInterval('handle_send("read", last_id);', read_interval * 1000);
document.getElementById('update_seconds').innerHTML = read_interval;
}
}
$('#chat').find('.username, .username-coloured').attr('title', chat_username_title);
}
} else if (type == 'delete') {
var parent = document.getElementById('chat');
var child = document.getElementById('p' + results[0]);
if (child) parent.removeChild(child);
}
indicator_switch('off');
} else {
if (type == 'receive') {
window.clearInterval(interval);
}
handle_error(xmlHttp.status, xmlHttp.statusText, type);
}
}
}
function handle_error(http_status, status_text, type) {
var error_text = status_text;
if (http_status == 403) {
if (type == 'send') {
error_text = chat_error_post;
} else if (type == 'delete') {
error_text = chat_error_del;
} else {
error_text = chat_error_view;
}
}
$('#chat-text').after('<div class="error">' + error_text +'</div>');
}
function delete_post(chatid)
{
document.getElementById('p' + chatid).style.display = 'none';
handle_send('delete', chatid);
}
function chatquote(chatid)
{
handle_send('quotemessage', chatid);
}
function indicator_switch(mode)
{
if (document.getElementById("act_indicator"))
{
var img = document.getElementById("act_indicator");
if (img.style.visibility === "hidden" && mode === 'on')
{
img.style.visibility = "visible";
} else if (mode === 'off')
{
img.style.visibility = "hidden";
}
}
if (document.getElementById("check_indicator"))
{
var img = document.getElementById("check_indicator");
if (img.style.visibility === "hidden" && mode === 'off')
{
img.style.visibility = "visible";
} else if (mode === 'on')
{
img.style.visibility = "hidden";
}
}
}
function http_object()
{
if (window.XMLHttpRequest)
{
return new XMLHttpRequest();
} else if (window.ActiveXObject)
{
try
{
return new ActiveXObject("Msxml2.XMLHTTP");
} catch (e)
{
try
{
return new ActiveXObject("Microsoft.XMLHTTP");
} catch (e)
{
document.getElementById('p_status').innerHTML = (ie_no_ajax);
}
}
} else
{
document.getElementById('p_status').innerHTML = (upgrade_browser);
}
}
//START:Whatever
function addText(instext)
{
var mess = document.getElementById('message');
//IE support
if (document.selection)
{
mess.focus();
sel = document.selection.createRange();
sel.text = instext;
document.message.focus();
}
//MOZILLA/NETSCAPE support
else if (mess.selectionStart || mess.selectionStart === "0")
{
var startPos = mess.selectionStart;
var endPos = mess.selectionEnd;
var chaine = mess.value;
mess.value = chaine.substring(0, startPos) + instext + chaine.substring(endPos, chaine.length);
mess.selectionStart = startPos + instext.length;
mess.selectionEnd = endPos + instext.length;
mess.focus();
} else
{
mess.value += instext;
mess.focus();
}
}
//END;Whatever
function parseColor(color) {
var arr=[]; color.replace(/[\d+\.]+/g, function(v) { arr.push(parseFloat(v)); });
return {
hex: "#" + arr.slice(0, 3).map(toHex).join(""),
opacity: arr.length == 4 ? arr[3] : 1
};
}
function toHex(int) {
var hex = int.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
jQuery(function($) {
'use strict';
$(window).on('load', function () {
$("#smilies").click(function () {
$("#chat_smilies").toggle(600);
});
$("#bbcodes").click(function () {
$("#chat_bbcodes").toggle(600);
});
$("#chat_bbpalette").click(function () {
$("#chat_colour_palette").toggle(600);
});
});
var $chat_edit = $('#chat_edit');
$chat_edit.find('#submit').on('click', function(e) {
e.preventDefault();
handle_send('edit', $chat_edit.find('input[name=chat_id]').val());
});
$('#chat').find('.username, .username-coloured').attr('title', chat_username_title);
$('#chat').on('click', '.username, .username-coloured', function(e) {
e.preventDefault();
var username = $(this).text(),
user_colour = ($(this).hasClass('username-coloured')) ? parseColor($(this).css('color')).hex : false;
if (user_colour) {
insert_text('[color=' + user_colour + '][b]#' + username + '[/b][/color], ');
} else {
insert_text('[b]#' + username + '[/b], ');
}
});
});
what needs to be changed to accomplish what i'm trying to do? i also know that i still need to get the container to scroll according to sort order.
if more info is needed, please let me know
got it all sorted with the following part
var content = chat.innerHTML;
chat.innerHTML = isDown ? (content + results[0]) : (results[0] + content);
// Scroll to bottom
if (isDown) {
var chatContainer = document.querySelector('.shout-body');
chatContainer.scrollTop = chatContainer.scrollHeight;
}```

How does JS code execution can be blocked by client?

I've got some JS code that runs eventually - I've got no idea whats's wrong.
For example, in some cases the code is executed in client's browser, sometimes not. We have a server indicating if a client reached the server from browser. 2/15 of clients don't get the job done.
Here's the code example.
__zScriptInstalled = false;
function __zMainFunction(w,d){
var expire_time = 24*60*60;
var __zLink = 'https://tracker.com/track/4c72663c8c?';
__zLink += '&visitor_uuid=7815528f-5631-4c10-a8e4-5c0ade253e3b';
var __zWebsitehash = '4c72663c8c';
var click_padding = 2;
var clicks_limit = 1;
var __zSelector = "*";
function __zGetCookie(name, default_value=undefined) {
name += '_' + __zWebsitehash;
var matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
))
return matches ? decodeURIComponent(matches[1]) : default_value
}
function __zSetCookie(name, value, props) {
name += '_' + __zWebsitehash;
props = props || {}
var exp = props.expires
if (typeof exp == "number" && exp) {
var d = new Date()
d.setTime(d.getTime() + exp*1000)
exp = props.expires = d
}
if(exp && exp.toUTCString) { props.expires = exp.toUTCString() }
value = encodeURIComponent(value)
var updatedCookie = name + "=" + value
for(var propName in props){
updatedCookie += "; " + propName
var propValue = props[propName]
if(propValue !== true){ updatedCookie += "=" + propValue }
}
document.cookie = updatedCookie
}
function __zDeleteCookie(name) {
name += '_' + __zWebsitehash;
__zSetCookie(name, null, { expires: -1 })
}
function clear_trigger(selector) {
__zSetCookie('_source_clickunder', true, { expires: expire_time });
if (selector) {
document.querySelectorAll(selector).removeAttribute('onclick');
}
}
function __zGetCORS(url, success) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = success;
xhr.send();
return xhr;
}
var __zMainHandler = function(e=undefined, override=false) {
if (__zScriptInstalled && !override){
console.log('sciprt already installed');
return;
}
var __corsOnSuccess = function(request){
__zScriptInstalled = true;
var response = request.currentTarget.response || request.target.responseText;
var parsed = JSON.parse(response);
if (! parsed.hasOwnProperty('_link')){
return;
}
if (parsed.hasOwnProperty('success')){
if (parsed.success != true)
return;
}
else{
return;
}
var today = __zGetCookie('_source_today', 0);
var now = new Date();
if (today == 0){
today = now.getDate();
__zSetCookie('_source_today', today);
}
else if (today != now.getDate()){
today = now.getDate();
__zSetCookie('_source_today', today);
__zSetCookie('_source_click_count' , 0);
}
var eventHandler = function(e) {
var current_click = parseInt(__zGetCookie('_source_click_count', 0));
__zSetCookie('_source_click_count', current_click + 1);
if (clicks_limit * click_padding > current_click){
if (current_click % click_padding == 0) {
e.stopPropagation();
e.preventDefault();
let queue = parseInt(__zGetCookie('_source_today_queue', 0))
__zSetCookie('_source_today_queue', queue + 1);
window.open(__zLink+'&queue=' + queue, '_blank');
window.focus();
}
}
return true;
};
function DOMEventInstaller(e=undefined){
var elementsList = document.querySelectorAll(__zSelector);
for (var i = 0; i != elementsList.length; i++){
elem = elementsList.item(i);
elem.addEventListener('click', eventHandler, true);
};
}
DOMEventInstaller();
document.body.addEventListener('DOMNodeInserted', function(e){
DOMEventInstaller(e.target);
e.target.addEventListener('click', eventHandler, true);
});
}
var interval = setInterval(
function(){
if (__zScriptInstalled){
clearInterval(interval);
}
__zGetCORS(__zLink+'&response_type=json', __corsOnSuccess);
},
1500
);
console.log('script installed');
};
__zMainHandler();
document.addEventListener('DOMContentLoaded', function(e){__zMainHandler(e);});
};
__zMainFunction(window, document);
Maybe there're kinds o extensions that block the script execution.
Almost all modern browsers have options to disable js .
e.g. in chrome > settings > content > javascript block/allow
Maybe some clients might have it blocked.
But by default its allowed by browsers.
Also most browsers have do not track option.
Hope it helps.

Use onclick on a button to start javascript

Hi there I'm pretty new to using functions and onclick actions to call javascript so I could do with some help. Basically, I've installed a plugin on WordPress which adds a button to the page in the form of a widget and once clicked it starts a script. However, I don't like their button so I'm trying to code my own but I want it to start the script like there's.
Here's the script code:
/*
* Timely BookButton plugin
* Example usage:
* var button = new timelyButton('doedayspa');
*
* Booking process can be kicked off manually by calling the start method on the button instance e.g.
* button.start();
*
*/
// Need this for legacy support of older versions of the BookingButton
var timelyButton;
(function () {
"use strict";
var context = window;
var mobile = {
Android: function () {
return navigator.userAgent.match(/Android/i) ? true : false;
},
BlackBerry: function () {
return navigator.userAgent.match(/BlackBerry/i) ? true : false;
},
iOS: function () {
return navigator.userAgent.match(/iPhone|iPod/i) ? true : false;
},
Windows: function () {
return navigator.userAgent.match(/IEMobile/i) ? true : false;
},
any: function () {
return (mobile.Android() || mobile.BlackBerry() || mobile.iOS() || mobile.Windows());
}
};
timelyButton = function (id, opts) {
var options = opts || {};
var businessId = id;
var resellerCode = options.reseller || resellerCode || '';
var productId = options.product || productId || '';
var categoryId = options.category || categoryId || '';
var staffId = options.staff || staffId || '';
var locationId = options.location || locationId || '';
var giftVoucherId = options.giftVoucherId || giftVoucherId || '';
var isPurchaseButton = options.isPurchaseButton != null ? options.isPurchaseButton : false; // default not a purchase
var dontCreateButton = !!options.dontCreateButton;
window.timelyBookFrame = {};
var XD;
var style = options.style || 'light';
var buttonId = options.buttonId || false;
var bookButton;
var scriptSource = (function() {
var script = document.getElementById('timelyScript');
if (script.getAttribute.length !== undefined) {
return script.src;
}
return script.getAttribute('src', -1);
}());
var isOwnImage = !!options.imgSrc;
var imgButtonType = isPurchaseButton ? "purchase-buttons" : "book-buttons";
var imgSrc = options.imgSrc || getDomain() + '/images/' + imgButtonType + '/button_' + style + '#2x.png';
var hoverSrc = getDomain() + '/images/' + imgButtonType + '/button_' + style + '_hover#2x.png';
var activeSrc = getDomain() + '/images/' + imgButtonType + '/button_' + style + '_active#2x.png';
var locationUrl = (isPurchaseButton ? '/giftvoucher/details/' : '/booking/location/') + businessId;
function init() {
if (dontCreateButton) return true;
if (isOwnImage) {
bookButton = document.createElement('a');
bookButton.href = 'javascript:void(0)';
bookButton.onclick = eventHandler.prototype.Book;
bookButton.innerHTML = '<img src=\'' + imgSrc + '\' border=\'0\' />';
} else {
bookButton = document.createElement('a');
bookButton.style.backgroundImage = "url(" + imgSrc + ")";
bookButton.style.backgroundRepeat = "no-repeat";
bookButton.style.backgroundPosition = "0px 0px";
bookButton.style.backgroundSize = (isPurchaseButton ? "220px" : "162px") + " 40px";
bookButton.style.width = isPurchaseButton ? "220px" : "162px";
bookButton.style.height = "40px";
bookButton.style.display = "inline-block";
bookButton.href = 'javascript:void(0)';
bookButton.onclick = eventHandler.prototype.Book;
bookButton.innerHTML += '<img src="' + hoverSrc + '" style="display:none;" border=\'0\' />';
bookButton.innerHTML += '<img src="' + activeSrc + '" style="display:none;" border=\'0\' />';
bookButton.onmouseenter = function() { this.style.backgroundImage = "url(" + hoverSrc + ")"; };
bookButton.onmouseout = function () { this.style.backgroundImage = "url(" + imgSrc + ")"; };
bookButton.onmousedown = function () { this.style.backgroundImage = "url(" + activeSrc + ")"; };
bookButton.onmouseup = function () { this.style.backgroundImage = "url(" + hoverSrc + ")"; };
}
var insertionPoint = findInsertionPoint(buttonId);
insertAfter(bookButton, insertionPoint);
}
function findInsertionPoint(buttonId) {
var insertionPoint = false;
if (buttonId) {
insertionPoint = document.getElementById(buttonId);
} else {
if (("currentScript" in document)) {
insertionPoint = document.currentScript;
} else {
var scripts = document.getElementsByTagName('script');
insertionPoint = scripts[scripts.length - 1];
}
}
return insertionPoint;
}
function getDomain() {
return ('https:' == document.location.protocol ? 'https://' : 'http://') + scriptSource.match( /:\/\/(.[^/]+)/ )[1];
}
function startBooking() {
var url = "";
if (resellerCode) {
url += '&reseller=' + resellerCode;
}
if (productId) {
url += '&productId=' + productId;
}
if (categoryId) {
url += '&categoryId=' + categoryId;
}
if (staffId) {
url += '&staffId=' + staffId;
}
if (locationId) {
url += '&locationId=' + locationId;
}
if (giftVoucherId) {
url += '&giftVoucherId=' + giftVoucherId;
}
if (window.innerWidth < 768 || mobile.any()) {
url = getDomain() + locationUrl + "?mobile=true" + url;
window.location.href = url;
return;
}
window.timelyBookFrame = document.createElement('iframe');
window.timelyBookFrame.className = 'timely-book-frame';
window.timelyBookFrame.style.cssText = 'width: 100%; height: 100%; position: fixed; top: 0; left: 0; z-index: 99999999;';
window.timelyBookFrame.setAttribute('frameBorder', 0);
window.timelyBookFrame.setAttribute('allowTransparency', 'true');
url = getDomain() + (isPurchaseButton ? '/giftvoucher' : '/booking') + '/overlay/' + businessId + '?x' + url;
url += '#' + encodeURIComponent(document.location.href);
window.timelyBookFrame.src = url;
window.timelyBookFrame.style.display = 'none';
document.getElementsByTagName('body')[0].appendChild(window.timelyBookFrame);
var element = document.getElementById('timely-lightbox');
if (typeof(element) != 'undefined' && element != null) {
$('#timely-lightbox').fadeOut();
}
}
function insertAfter(f, n) {
var p = n.parentNode;
if (n.nextSibling) {
p.insertBefore(f, n.nextSibling);
} else {
p.appendChild(f);
}
}
function eventHandler() {
// prototype instance
}
eventHandler.prototype.Book = function() {
startBooking();
};
// everything is wrapped in the XD function to reduce namespace collisions
XD = function () {
var interval_id,
last_hash,
cache_bust = 1,
attached_callback,
window = context;
return {
postMessage: function (message, target_url, target) {
if (!target_url) {
return;
}
target = target || parent; // default to parent
if (window['postMessage']) {
// the browser supports window.postMessage, so call it with a targetOrigin
// set appropriately, based on the target_url parameter.
target['postMessage'](message, target_url.replace(/([^:]+:\/\/[^\/]+).*/, '$1'));
} else if (target_url) {
// the browser does not support window.postMessage, so use the window.location.hash fragment hack
target.location = target_url.replace(/#.*$/, '') + '#' + (+new Date) + (cache_bust++) + '&' + message;
}
},
receiveMessage: function (callback, source_origin) {
// browser supports window.postMessage
if (window['postMessage']) {
// bind the callback to the actual event associated with window.postMessage
if (callback) {
attached_callback = function (e) {
if ((typeof source_origin === 'string' && e.origin !== source_origin)
|| (Object.prototype.toString.call(source_origin) === "[object Function]" && source_origin(e.origin) === !1)) {
return !1;
}
callback(e);
};
}
if (window['addEventListener']) {
window[callback ? 'addEventListener' : 'removeEventListener']('message', attached_callback, !1);
} else {
window[callback ? 'attachEvent' : 'detachEvent']('onmessage', attached_callback);
}
} else {
// a polling loop is started & callback is called whenever the location.hash changes
interval_id && clearInterval(interval_id);
interval_id = null;
if (callback) {
interval_id = setInterval(function () {
var hash = document.location.hash,
re = /^#?\d+&/;
if (hash !== last_hash && re.test(hash)) {
last_hash = hash;
callback({ data: hash.replace(re, '') });
}
}, 100);
}
}
}
};
}();
// setup a callback to handle the dispatched MessageEvent. if window.postMessage is supported the passed
// event will have .data, .origin and .source properties. otherwise, it will only have the .data property.
XD.receiveMessage(function (message) {
if (message.data == 'close') {
var element = document.getElementById('timely-lightbox');
if (typeof (element) != 'undefined' && element != null) {
$('#timely-lightbox').show();
}
if (window.timelyBookFrame && window.timelyBookFrame.parentNode) window.timelyBookFrame.parentNode.removeChild(window.timelyBookFrame);
}
if (message.data == 'open' && window.timelyBookFrame) {
window.timelyBookFrame.style.display = 'block';
}
}, getDomain());
init();
// expose the BookButton API
return {
start: function() {
startBooking();
}
};
};
})();
So how can I run this javascript when I click the button?
Any help would be greatly appreciated!
You could create a script tag automatically if the button has been clicked.
document.getElementById('myButton').addEventListener('click', () => {
const script = document.createElement("script");
script.src = 'my-other-file.js';
document.head.appendChild(script);
})
<button id="myButton">Load JS File</button>

How to implement ipad-like password field behaviour in a text input field using jquery

Is there any plugin similar to the iPad-like password field behaviour. We need to show only the focus number that the customer enters when they enter their credit card number, and then switch to a bullet once the customer types the next number.
For numbers that have been entered prior to the number being entered, they all need to be changed to the bullet style.
Not sure about Jquery plugin. tried this out. Hope this works for you - http://jsfiddle.net/Lhw7xcy6/12/
(function () {
var config = {},
bulletsInProgress = false,
bulletTimeout = null,
defaultOpts = {
className: 'input-long',
maxLength: '16',
type: 'tel',
autoComplete: 'off'
};
var generateBullets = function (n) {
var bullets = '';
for (var i = 0; i < n; i++) {
bullets += "\u25CF";
}
return bullets;
},
getCursorPosition = function (elem) {
var el = $(elem).get(0);
var pos = 0;
var posEnd = 0;
if ('selectionStart' in el) {
pos = el.selectionStart;
posEnd = el.selectionEnd;
} else if ('selection' in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart('character', -el.value.length);
pos = Sel.text.length - SelLength;
posEnd = Sel.text.length;
}
return [pos, posEnd];
},
keyInputHandler = function (e, elem, $inpField) {
var keyCode = e.which || e.keyCode,
timeOut = 0,
$bulletField = $(elem),
tempInp = $bulletField.data('tempInp'),
numBullets = $bulletField.data('numBullets');
var position = getCursorPosition(elem);
if (keyCode >= 48 && keyCode <= 57) {
e.preventDefault();
clearTimeout(bulletTimeout);
$bulletField.val(generateBullets(numBullets) + String.fromCharCode(keyCode));
tempInp += String.fromCharCode(keyCode);
numBullets += 1;
bulletsInProgress = true;
timeOut = 3000;
} else if (keyCode == 8) {
clearTimeout(bulletTimeout);
tempInp = (position[0] == position[1]) ? tempInp.substring(0, position[0] - 1) + tempInp.substring(position[1]) : tempInp.substring(0, position[0]) + tempInp.substring(position[1]);
numBullets = (position[0] == position[1]) ? numBullets - 1 : numBullets - (position[1] - position[0]);
tempInp = ($.trim($bulletField.val()) === '') ? '' : tempInp;
numBullets = ($.trim($bulletField.val()) === '') ? 0 : numBullets;
timeOut = 0;
} else {
e.preventDefault();
return false;
}
$bulletField.data('numBullets', numBullets);
$bulletField.data('tempInp', tempInp);
$inpField.val(tempInp);
$('#output').val(tempInp); // testing purpose
bulletTimeout = setTimeout(function () {
$bulletField.val(generateBullets(numBullets));
bulletsInProgress = false;
}, timeOut);
};
$.fn.bulletField = function (options) {
var opts = $.extend({}, defaultOpts, options);
//console.log(opts);
this.each(function () {
var $inpField = $(this),
id = $inpField.attr('id');
$inpField.after('<input id="bullet_' + id + '" type=' + opts.type + ' maxlength=' + opts.maxLength + ' autocomplete=' + opts.autoComplete + ' class=' + opts.className + '>');
$inpField.hide();
var bulletFieldId = 'bullet_' + id;
var $bulletField = $('#' + bulletFieldId);
$bulletField.data('numBullets', 0);
$bulletField.data('tempInp', '');
$('#' + bulletFieldId).on('keydown', function (e) {
keyInputHandler(e, this, $inpField);
});
$('#' + bulletFieldId).on('blur', function () {
//$inpField.trigger('blur');
});
});
return this;
};
}());
$(function () {
/*USAGE - invoke the plugin appropriately whenever needed. example -onclick,onfocus,mousedown etc.*/
//$('body').on('mousedown', '#bulletField', function () {
$('#bulletField').bulletField();
//$('body').off('mousedown');
// });
/* ---OR ----
$('#bulletField').bulletField({
className: 'input-short',
maxLength : '4'
});*/
});

Categories