How can I catch a click event objects attribute using javascript only? - javascript

I have the following coded using jQuery:
$('.status-infos').click( function (e) {
var xx = $(this).attr('data-xx');
alert(xx);
return false;
});
Our site main page will no longer use jQuery and so I need to do something similar to this using only javascript.
I saw this as a way to get the click event:
document.getElementById('element').onclick = function(e){
alert('click');
}
but how can I get the xx attribute.

You can use:
document.getElementsByClassName('status-infos')
Then loop over that array and use.. onclick = function() {}
Use: element.getAttribute() to get the data attribute

Solution for modern browsers:
var els = document.querySelectorAll(".status-infos");
for (var i = 0; i < els.length; i++) {
els[i].addEventListener("click", function() {
var xx = this.getAttribute("data-xx");
alert(xx);
return false;
});
}

Here is the complete version for IE8+ as well
DEMO
function getElementsByClassName(className) {
if (document.getElementsByClassName) {
return document.getElementsByClassName(className); }
else { return document.querySelectorAll('.' + className); } }
window.onload=function() {
var statinf = getElementsByClassName("status-infos");
for (var i=0;i<statinf.length;i++) {
statinf[i].onclick=function() {
var xx = this.getAttribute('data-xx');
alert(xx);
return false;
}
}
}

jQuery has always made developers lazy.. Try this code:
/* http://dustindiaz.com/rock-solid-addevent */
function addEvent(obj, type, fn) {
if (obj.addEventListener) {
obj.addEventListener(type, fn, false);
EventCache.add(obj, type, fn);
}
else if (obj.attachEvent) {
obj["e" + type + fn] = fn;
obj[type + fn] = function() {
obj["e" + type + fn](window.event);
}
obj.attachEvent("on" + type, obj[type + fn]);
EventCache.add(obj, type, fn);
}
else {
obj["on" + type] = obj["e" + type + fn];
}
}
var EventCache = function() {
var listEvents = [];
return {
listEvents: listEvents,
add: function(node, sEventName, fHandler) {
listEvents.push(arguments);
},
flush: function() {
var i, item;
for (i = listEvents.length - 1; i >= 0; i = i - 1) {
item = listEvents[i];
if (item[0].removeEventListener) {
item[0].removeEventListener(item[1], item[2], item[3]);
};
if (item[1].substring(0, 2) != "on") {
item[1] = "on" + item[1];
};
if (item[0].detachEvent) {
item[0].detachEvent(item[1], item[2]);
};
item[0][item[1]] = null;
};
}
};
}();
/* http://www.dustindiaz.com/getelementsbyclass */
function getElementsByClass(searchClass,node,tag) {
var classElements = new Array();
if ( node == null )
node = document;
if ( tag == null )
tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
var statuss=getElementsByClass('status-infos');
for (var i=0;i<statuss.length;i++){
addEvent(statuss[i], 'click', function (e) {
var xx = this.getAttribute('data-xx');
alert(xx);
return false;
});
}
Demo | Demo Source

Use an addEventListener or attachEvent (IE).
var elements = document.getElementByClassName('status-infos');
for(var i=0; i < elements.length; i++) {
elements[i].addEventListener('click', function(e) {
...
});
}
More info

Related

How to take the result of one script and feed it into another?

I'm in way over my head here and need some help to understand what I'm looking at please! (Very new to Javascript!) Here is the situation as I understand it...
I have a script that is selecting a single line from a paragraph of text, and currently produces this alert, where '1' is the selected line:
alert(getLine("sourcePara", 1));
...Instead of triggering an alert I need this selected text to feed into this separate script which is sending data to another browser window. Presently it's taking a text field from a form with the id 'STOCK1', but that can be replaced:
function sendLog() {
var msg = document.getElementById('STOCK1').value;
t.send('STK1', msg);
}
I'm totally confused as to what form this text data is taking on the way out of the first script and have no idea how to call it in as the source for the second... HELP!
All the thanks!
EDIT:
Here is the source code for the Local Connection element;
function LocalConnection(options) {
this.name = 'localconnection';
this.id = new Date().getTime();
this.useLocalStorage = false;
this.debug = false;
this._actions= [];
this.init = function(options) {
try {
localStorage.setItem(this.id, this.id);
localStorage.removeItem(this.id);
this.useLocalStorage = true;
} catch(e) {
this.useLocalStorage = false;
}
for (var o in options) {
this[o] = options[o];
}
this.clear();
}
this.listen = function() {
if (this.useLocalStorage) {
if (window.addEventListener) {
window.addEventListener('storage', this.bind(this, this._check), false);
} else {
window.attachEvent('onstorage', this.bind(this, this._check));
}
} else {
setInterval(this.bind(this, this._check), 100);
}
}
this.send = function(event) {
var args = Array.prototype.slice.call(arguments, 1);
return this._write(event, args);
}
this.addCallback = function(event, func, scope) {
if (scope == undefined) {
scope = this;
}
if (this._actions[event] == undefined) {
this._actions[event] = [];
}
this._actions[event].push({f: func, s: scope});
}
this.removeCallback = function(event) {
for (var e in this._actions) {
if (e == event) {
delete this._actions[e];
break;
}
}
}
this._check = function() {
var data = this._read();
if (data.length > 0) {
for (var e in data) {
this._receive(data[e].event, data[e].args);
}
}
}
this._receive = function(event, args) {
if (this._actions[event] != undefined) {
for (var func in this._actions[event]) {
if (this._actions[event].hasOwnProperty(func)) {
this.log('Triggering callback "'+event+'"', this._actions[event]);
var callback = this._actions[event][func];
callback.f.apply(callback.s, args);
}
}
}
};
this._write = function(event, args) {
var events = this._getEvents();
var evt = {
id: this.id,
event: event,
args: args
};
events.push(evt);
this.log('Sending event', evt);
if (this.useLocalStorage) {
localStorage.setItem(this.name, JSON.stringify(events));
} else {
document.cookie = this.name + '=' + JSON.stringify(events) + "; path=/";
}
return true;
}
this._read = function() {
var events = this._getEvents();
if (events == '') {
return false;
}
var ret = [];
for (var e in events) {
if (events[e].id != this.id) {
ret.push({
event: events[e].event,
args: events[e].args
});
events.splice(e, 1);
}
}
if (this.useLocalStorage) {
localStorage.setItem(this.name, JSON.stringify(events));
} else {
document.cookie = this.name + '=' + JSON.stringify(events) + "; path=/";
}
return ret;
}
this._getEvents = function() {
return this.useLocalStorage ? this._getLocalStorage() : this._getCookie();
}
this._getLocalStorage = function() {
var events = localStorage.getItem(this.name);
if (events == null) {
return [];
}
return JSON.parse(events);
}
this._getCookie = function() {
var ca = document.cookie.split(';');
var data;
for (var i=0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1, c.length);
}
if (c.indexOf(this.name+'=') == 0) {
data = c.substring(this.name.length+1, c.length);
break;
}
}
data = data || '[]';
return JSON.parse(data);
}
this.clear = function() {
if (this.useLocalStorage) {
localStorage.removeItem(this.name);
} else {
document.cookie = this.name + "=; path=/";
}
}
this.bind = function(scope, fn) {
return function () {
fn.apply(scope, arguments);
};
}
this.log = function() {
if (!this.debug) {
return;
}
if (console) {
console.log(Array.prototype.slice.call(arguments));
}
}
this.init(options);
}
If I understand what you are asking for correctly, then I think its a matter of changing your log function to the following:
function sendLog() {
t.send('STK1', getLine("sourcePara", 1));
}
This assumes that getLine is globally accessible.
Alternatively Another approach would be to allow for the sendLog function to take the message as a parameter. In which case, you would change your first script to be:
sendLog(getLine("sourcePara", 1));
And the modified sendLog function would look like this:
function sendLog(msg) {
t.send('STK1', msg);
}
LocalConnection.js should handle transferring the data between windows/tabs. Looks like an an iteresting project:
https://github.com/jeremyharris/LocalConnection.js

want to add AND search to this incremental search plugin

I want to add AND search function to a following incremental search jQuery plugin that can search option elements from select-boxes.
JSFiddle
I'm trying to do these ideas but can't code successfully.
- first of all I want to define white space as a delimiter.
- next I want to distinguish that variable from other white spaces in option elements.
By the way, I don't want to replace a lot of DOM elements.
So, I don't want to use plugin like selectize.js, nether datalist elements anyway.
Somebody help?
(function ($, window, document, undefined) {
'use strict';
var pluginName = "selectboxsearch",
defaults = {
delay: 100,
bind: 'keyup',
};
function Plugin(element, target, options) {
this.element = element;
this.$element = $(element);
this.target = target;
this.options = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.vars = {
optionRows: $(this.target).children().map(function () {
return this;
})
};
this.init();
}
Plugin.prototype = {
init: function () {
var self = this,
delay = this.options.delay;
this.$element.on(this.options.bind, function () {
var timeout = window.setTimeout(function () {
self.go();
}, delay);
});
},
go: function () {
var array = this.vars.optionRows,
val = this.$element.val();
//一周目のみ
for (var n = 0; n < 1; n++) {
// いったん削除
$(this.target).children().remove();
for (var i = 0, len = array.length; i < len; i++) {
if (array[i]) {
//option内のスペースを除去
var pos = array[i].innerHTML.toLowerCase().replace(/ /g,'').indexOf(val, 0);
// キーワードが空、もしくはヒットした場合要素追加
if ((val.replace(/ /g,'').length === 0) || pos >= 0) {
$(this.target).append(array[i]);
}
}
}
}
},
additem: function (items) {
var self = this,
array = this.vars.optionRows,
len = this.vars.optionRows.length;
$.each(items, function (index, item) {
var add = true;
for (var i = 0, len; i < len; i++) {
if (item.value == array[i].value) {
add = false;
}
}
if (add == true) {
array.push(item);
}
});
this.vars.optionRows = array;
self.go();
},
delitem: function (items) {
var self = this,
array = [];
$.each(this.vars.optionRows, function (index, item) {
var del = false;
for (var i = 0, len = items.length; i < len; i++) {
if (item.value == items[i].value) {
del = true;
}
}
if (del == false) {
array.push(item);
}
});
this.vars.optionRows = array;
self.go();
}
};
$.fn[pluginName] = function (target, options) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin($(this), target, options));
}
});
};
function _fnGetMaxLenString(settings, colIdx) {
var s, max = -1,
maxIdx = -1;
for (var i = 0, ien = settings.aoData.length; i < ien; i++) {
s = _fnGetCellData(settings, i, colIdx, 'display') + '';
s = s.replace(__re_html_remove, '');
s = s.replace(' ', ' ');
if (s.length > max) {
max = s.length;
maxIdx = i;
}
}
return maxIdx;
}
})(jQuery, window, document);

Run function inside another function

If I run this code:
var alts = {};
$('.grid ul').find('.lista-produtos:visible').each(function(){
var classes2 = $(this).attr('class').split(' ');
for (var i = 0; i < classes2.length; i++) {
var matches2 = /^tipo\-(.+)/.exec(classes2[i]);
if (matches2 != null) {
var produto2 = matches2[1];
}
}
if(!alts[classes2]){
alts[classes2] = true;
$('ul.filters').append('<li class="filter-produto">'+ produto2 +'</li>');
}
});
as a function, like this:
function tipoProduto(){
var alts = {};
$('.grid ul').find('.lista-produtos:visible').each(function(){
var classes2 = $(this).attr('class').split(' ');
for (var i = 0; i < classes2.length; i++) {
var matches2 = /^tipo\-(.+)/.exec(classes2[i]);
if (matches2 != null) {
var produto2 = matches2[1];
}
}
if(!alts[classes2]){
alts[classes2] = true;
$('ul.filters').append('<li class="filter-produto">'+ produto2 +'</li>');
}
});
}
and call it here:
$('.list-group-item').click(function(){
var classes1 = $(this).attr('class').split(' ');
for (var i = 0; i < classes1.length; i++) {
var matches1 = /^ctrl\-(.+)/.exec(classes1[i]);
if (matches1 != null) {
var marca1 = matches1[1];
}
}
$(this).addClass("active");
$('.list-group-item').not(this).removeClass("active");
if ($('.todos-produtos').hasClass("active")) {
$('.lista-produtos').hide();
$('.' + marca1).show();
}
else {
var produto1 = $('li.filter-produto.active').text();
$('.lista-produtos').not('.' + marca1 + '.tipo-' + produto1).hide();
$('.' + marca1 + '.tipo-' + produto1).show()
}
tiposProduto(); // CALLING IT HERE //
});
});
then this code below doesn't work:
$(document).ready(function(){
$('.filter-produto').click(function() {
var classes3 = $('.list-group-item.active').attr('class').split(' ');
for (var i = 0; i < classes3.length; i++) {
var matches3 = /^ctrl\-(.+)/.exec(classes3[i]);
if (matches3 != null) {
var marca2 = matches3[1];
}
}
$(this).addClass("active");
$('.filter-produto').not(this).removeClass("active");
if ($(this).hasClass("todos-produtos")) {
$('.' + marca2).show();
}
else {
var produto3 = $(this).text();
$(".lista-produtos").not('.tipo-' + produto3).hide();
$('.' + marca2 + '.tipo-' + produto3).show();
}
});
});
but if I change the 1st code to this:
$(document).ready(function(){
var alts = {};
$('.grid ul').find('.lista-produtos:visible').each(function(){
var classes2 = $(this).attr('class').split(' ');
for (var i = 0; i < classes2.length; i++) {
var matches2 = /^tipo\-(.+)/.exec(classes2[i]);
if (matches2 != null) {
var produto2 = matches2[1];
}
}
if(!alts[classes2]){
alts[classes2] = true;
$('ul.filters').append('<li class="filter-produto">'+ produto2 +'</li>');
}
});
});
then the 4th code works again.
The problem is I need the code above as a function, like I showed on the 2nd and 3rd examples.
Thanks!
Thanks for the few replies. I found out the problem.
Appended objects weren't being recognized by the functions. That's why $('.filter-produto').click(function() { wasn't working.

Send object this to functions that take No-arguments

How can i send parameter this to function.
Above options work in constructor :
selectors[i].onblur = this.validation;
But if in function Valid i call the selectors[i].validation, above solution will not working. Does Somebody know, how to call selectors[i].validation with parameter this??
For any help, i will be very grateful.
link to demo:
http://codepen.io/anon/pen/YqryVr
My js classes:
var Validator = (function () {
var errorClassName = "error";
var selectors;
var regexMap;
function Validator(id, regexObject) {
if (id === void 0) { id = "form"; }
regexMap = regexObject.getMap();
selectors = document.getElementById(id).elements;
for (i = 0; i < selectors.length; ++i) {
selectors[i].onblur = this.validation;
}
};
Validator.prototype.setErrorClassName = function (className) {
errorClassName = className;
};
Validator.prototype.addClass = function (selector) {
if(selector.className.indexOf(errorClassName) < 1)
selector.className += " " + errorClassName;
};
Validator.prototype.removeClass = function (selector) {
selector.className = selector.className.replace(errorClassName, '');
};
Validator.prototype.validation = function () {
alert('this.type: ' + this.type);
switch(this.type) {
case 'textarea':
case 'text':
if(this.dataset.regex in regexMap) this.dataset.regex = regexMap[this.dataset.regex];
var pattern = new RegExp(this.dataset.regex);
if(this.value.length !== 0 && pattern.test(this.value)) {
Validator.prototype.removeClass(this);
return true;
} else {
Validator.prototype.addClass(this);
return false;
}
break;
case 'select-one':
if(this.value.length === 0) {
Validator.prototype.addClass(this);
return false;
} else {
Validator.prototype.removeClass(this);
return true;
}
break;
}
return true;
};
Validator.prototype.valid = function () {
for (i = 0; i < selectors.length; ++i) {
selectors[i].validation;
}
return true;
};
return Validator;
}());
var SelectorAttribute = (function () {
function SelectorAttribute(name, regex) {
this.name = name;
this.regex = regex;
}
SelectorAttribute.prototype.toString = function () {
return "name: " + this.name + ", regex = " + this.regex;
};
return SelectorAttribute;
}());
var StandardRegexPatterns = (function () {
var map = {};
function StandardRegexPatterns() {
map['zip-code-poland'] = '^[0-9]{2}-[0-9]{3}$';
map['phone-number-poland'] = '^[0-9]{9}$';
map['digits'] = '^[0-9]+$';
map['alpha'] = '^[a-zA-z]+$';
map['email'] = '^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*#([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?';
map['login'] = '^[a-z0-9_-\.]{3,21}$';
map['ip-address'] = '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$';
map['url-address'] = '^((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$';
}
StandardRegexPatterns.prototype.getMap = function () {
return map;
};
return StandardRegexPatterns;
}());
$( document ).ready(function() {
var validator = new Validator('form', new StandardRegexPatterns());
validator.setErrorClassName("error");
//var pattern = new StandardRegexPatterns();
// alert(Object.keys(pattern.getMap()));
$("button").on('click', function(){
alert(validator.valid());
});
});
You can use the following:
functionname.apply(this, [arguments]);
or
functionname.call(this, argument1, argument2);
if you don't have arguments you can just omit them.
I usually just do this:
funcitonname.apply(this, Arguments);
if I'm calling this method from within a function already so I can carry on the arguments to the functionname().
Learn more about apply
Learn more about call

document.createElement("<li>") not working in IE10?

In my below, it works fine upto IE9, but not in IE10+:
function createList() {
try {
var listObj = document.getElementById('dialedList');
//document.getElementById('dialedDiv').style.display = "inline";
var list = opener.dialedNumbers; // This is array
//alert("list : "+list);
for (var i = 0; i < list.length; i++) {
//alert(list[i])
if (list[i] != undefined && list[i] != null && list[i] != "") {
alert("come");
var li = document.createElement("<li>");
alert("not come");
li.innerHTML = list[i];
li.onclick = function () {
//alert(this);
document.getElementById('screen').value = this.innerHTML;
document.getElementById('screen').focus();
};
li.onmouseover = function () {
this.style.backgroundColor = "#719FE5";
this.focus();
};
li.onmouseout = function () {
this.style.backgroundColor = "white";
this.focus();
};
listObj.appendChild(li);
}
}
} catch (e) {
alert(e.description);
alert(e.message);
}
}
createElement doesn't accept HTML, it accepts an element name ("tag name"). So you don't include the angle brackets:
var li = document.createElement("li");
If you've had other browsers accepting the previous version, they were just being tolerant.

Categories