Programmatic event binding using Kendo UI MVVM not working - javascript

I'm trying to programmatically bind events to fields. The "data-bind > events > change" attribute(s) is/are being added to the DOM element just fine. For instance, this is the HTML generated by my script:
<select id="MainContent_DetailsContent_TypeOfLoss" class="valid" name="TypeOfLoss" data-role="dropdownlist" data-text-field="text" data-value-field="value" data-bind="source: TypeOfLoss, events: { change: TypeOfLoss_updateSourceUsingValue }" style="display: none;">
However, when I change the value of the DropDownList (just for example), I get the following error:
TypeError: handler is not a function
path/to/app/Assets/Lib/kendo/src/js/kendo.web.js
Line 6923
I don't know what's going on - the TypeOfLoss_updateSourceUsingValue method/property DOES exist in the corresponding View-Model (KendoDOMBinder._viewModel).
Any ideas? I'm using kendoui.web.2013.1.319.
KendoDOMBinder: function (viewModel) {
var binder = Object.create({
_viewModel: {},
_widgets: {},
_root: {},
init: function (viewModel) {
this._viewModel = viewModel || Object.create(kendo.observable());
this._widgets = App.Config.Widgets.defaults();
return this;
},
bindField: function (node, bindings) {
var that = this,
val = [],
ds,
events = [],
event,
target,
fnCallback,
callback;
// Empty data attributes will crash Kendo
if (App.Utilities.isEmpty(bindings) === false) {
// TODO: Should be using strategy pattern to process data attributes
$.each(bindings, function (type, binding) {
switch (type) {
case 'source':
ds = App.Data.DataSource.Factory(binding)
val.push(type + ': ' + node.name);
that._viewModel.set(node.name, ds);
break;
case 'value':
// Make sure the property doesn't exist before adding it
if (that._viewModel.hasOwnProperty(binding) === false) {
// Add the property
that._viewModel.set(binding, '');
// TODO: accept function
}
break;
case 'events':
break;
case 'field':
event = binding.event || 'change';
type = binding.type;
target = binding.target;
if (binding.type == 'triggerUpdate') {
fnCallback = [node.name, binding.callback].join('_');
//console.log(fnCallback);
// Make sure the property doesn't exist before adding it
if (that._viewModel.hasOwnProperty(fnCallback) === false) {
// Define the callback
switch (binding.callback) {
case 'updateSourceUsingValue':
// Add the property
fnCallback = that._viewModel.set(fnCallback, function () {
alert("Doing something");
});
//console.log(that._viewModel);
events.push(event + ': ' + fnCallback);
break;
case 'updateUsingValue':
break;
}
}
}
break;
default:
val.push(type + ': ' + binding);
break;
}
});
if (events.length > 0) {
val.push('events: { ' + events.join(', ') + ' }');
}
}
console.log(val.join(', '));
node.setAttribute('data-bind', val.join(', '));
return this;
},
unbindField: function (key) {
//this._viewModel.unbind;
return this;
},
bind: function (selector) {
selector = selector || 'body';
kendo.bind($(selector), this._viewModel);
},
createFunction: function (ns, fn) {
var nsArray = ns.split(/\./),
currentNode = this._root,
newNS;
while (nsArray.length > 1) {
newNS = nsArray.shift();
if (typeof currentNode[newNS] === "undefined") {
currentNode[newNS] = {};
}
currentNode = currentNode[newNS];
}
if (fn) {
currentNode[nsArray.shift()] = fn;
} else {
currentNode[nsArray.shift()] = {};
}
}
});
return binder.init(viewModel);
}

Related

Tab Navigation not working for Autocomplete text box on Mozilla Firefox

I am using 'jquery.ui.autocomplete.js'. What issue I am facing is that during TAB Press default Naviagtion get stuck
when it reached in Autocomplete Text Box. The issue is reflecting only in Mozilla Firefox. What I want is that on TAB key press
it shold move to next elemnt. Can anyone please assist me to fix this issue?
I have tried Googled solutions but not able to fix. I am posting some link hope it will help you to understand isue.
1. http://bugs.jqueryui.com/ticket/6661
I think issue is somewhere in these lines:
case keyCode.ENTER:
case keyCode.NUMPAD_ENTER:
// when menu is open or has focus
if (self.menu.element.is(":visible")) {
event.preventDefault();
}
//passthrough - ENTER and TAB both select the current element
case keyCode.TAB:
if (!self.menu.active) {
return;
}
self.menu.select(event);
break;
case keyCode.ESCAPE:
self.element.val(self.term);
self.close(event);
break;
default:
// keypress is triggered before the input value is changed
clearTimeout(self.searching);
self.searching = setTimeout(function () {
// only search if the value has changed
if (self.term != self.element.val()) {
self.selectedItem = null;
self.search(null, event);
}
}, self.options.delay);
break;
}
})
My jquery code is here:
(function ($, undefined) {
$.widget("ui.autocomplete", {
options: {
appendTo: "body",
delay: 300,
minLength: 1,
position: {
my: "left top",
at: "left bottom",
collision: "none"
},
source: null
},
_create: function () {
var self = this,
doc = this.element[0].ownerDocument;
this.element
.addClass("ui-autocomplete-input")
.attr("autocomplete", "off")
// TODO verify these actually work as intended
.attr({
role: "textbox",
"aria-autocomplete": "list",
"aria-haspopup": "true"
})
.bind("keydown.autocomplete", function (event) {
if (self.options.disabled || self.element.attr("readonly")) {
return;
}
var keyCode = $.ui.keyCode;
switch (event.keyCode) {
case keyCode.PAGE_UP:
self._move("previousPage", event);
break;
case keyCode.PAGE_DOWN:
self._move("nextPage", event);
break;
case keyCode.UP:
self._move("previous", event);
// prevent moving cursor to beginning of text field in some browsers
event.preventDefault();
break;
case keyCode.DOWN:
self._move("next", event);
// prevent moving cursor to end of text field in some browsers
event.preventDefault();
break;
case keyCode.ENTER:
case keyCode.NUMPAD_ENTER:
// when menu is open or has focus
if (self.menu.element.is(":visible")) {
event.preventDefault();
}
//passthrough - ENTER and TAB both select the current element
case keyCode.TAB:
if (!self.menu.active) {
return;
}
self.menu.select(event);
break;
case keyCode.ESCAPE:
self.element.val(self.term);
self.close(event);
break;
default:
// keypress is triggered before the input value is changed
clearTimeout(self.searching);
self.searching = setTimeout(function () {
// only search if the value has changed
if (self.term != self.element.val()) {
self.selectedItem = null;
self.search(null, event);
}
}, self.options.delay);
break;
}
})
.bind("focus.autocomplete", function () {
if (self.options.disabled) {
return;
}
self.selectedItem = null;
self.previous = self.element.val();
})
.bind("blur.autocomplete", function (event) {
if (self.options.disabled) {
return;
}
clearTimeout(self.searching);
// clicks on the menu (or a button to trigger a search) will cause a blur event
self.closing = setTimeout(function () {
self.close(event);
self._change(event);
}, 150);
});
this._initSource();
this.response = function () {
return self._response.apply(self, arguments);
};
this.menu = $("<ul></ul>")
.addClass("ui-autocomplete")
.appendTo($(this.options.appendTo || "body", doc)[0])
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
.mousedown(function (event) {
// clicking on the scrollbar causes focus to shift to the body
// but we can't detect a mouseup or a click immediately afterward
// so we have to track the next mousedown and close the menu if
// the user clicks somewhere outside of the autocomplete
var menuElement = self.menu.element[0];
if (event.target === menuElement) {
setTimeout(function () {
$(document).one('mousedown', function (event) {
if (event.target !== self.element[0] &&
event.target !== menuElement &&
!$.ui.contains(menuElement, event.target)) {
self.close();
}
});
}, 1);
}
// use another timeout to make sure the blur-event-handler on the input was already triggered
setTimeout(function () {
clearTimeout(self.closing);
}, 13);
})
.menu({
focus: function (event, ui) {
var item = ui.item.data("item.autocomplete");
if (false !== self._trigger("focus", null, { item: item })) {
// use value to match what will end up in the input, if it was a key event
if (/^key/.test(event.originalEvent.type)) {
self.element.val(item.value);
}
}
},
selected: function (event, ui) {
var item = ui.item.data("item.autocomplete"),
previous = self.previous;
// only trigger when focus was lost (click on menu)
if (self.element[0] !== doc.activeElement) {
self.element.focus();
self.previous = previous;
}
if (false !== self._trigger("select", event, { item: item })) {
self.element.val(item.value);
}
self.close(event);
self.selectedItem = item;
},
blur: function (event, ui) {
// don't set the value of the text field if it's already correct
// this prevents moving the cursor unnecessarily
if (self.menu.element.is(":visible") &&
(self.element.val() !== self.term)) {
self.element.val(self.term);
}
}
})
.zIndex(this.element.zIndex() + 1)
// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
.css({ top: 0, left: 0 })
.hide()
.data("menu");
if ($.fn.bgiframe) {
this.menu.element.bgiframe();
}
},
destroy: function () {
this.element
.removeClass("ui-autocomplete-input")
.removeAttr("autocomplete")
.removeAttr("role")
.removeAttr("aria-autocomplete")
.removeAttr("aria-haspopup");
this.menu.element.remove();
$.Widget.prototype.destroy.call(this);
},
_setOption: function (key, value) {
$.Widget.prototype._setOption.apply(this, arguments);
if (key === "source") {
this._initSource();
}
if (key === "appendTo") {
this.menu.element.appendTo($(value || "body", this.element[0].ownerDocument)[0])
}
},
_initSource: function () {
var array,
url;
if ($.isArray(this.options.source)) {
array = this.options.source;
this.source = function (request, response) {
response($.ui.autocomplete.filter(array, request.term));
};
} else if (typeof this.options.source === "string") {
url = this.options.source;
this.source = function (request, response) {
$.getJSON(url, request, response);
};
} else {
this.source = this.options.source;
}
},
search: function (value, event) {
value = value != null ? value : this.element.val();
if (value.length < this.options.minLength) {
return this.close(event);
}
clearTimeout(this.closing);
if (this._trigger("search") === false) {
return;
}
return this._search(value);
},
_search: function (value) {
this.term = this.element
.addClass("ui-autocomplete-loading")
// always save the actual value, not the one passed as an argument
.val();
this.source({ term: value }, this.response);
},
_response: function (content) {
if (content.length) {
content = this._normalize(content);
this._suggest(content);
this._trigger("open");
} else {
this.close();
}
this.element.removeClass("ui-autocomplete-loading");
},
close: function (event) {
clearTimeout(this.closing);
if (this.menu.element.is(":visible")) {
this._trigger("close", event);
this.menu.element.hide();
this.menu.deactivate();
}
},
_change: function (event) {
if (this.previous !== this.element.val()) {
this._trigger("change", event, { item: this.selectedItem });
}
},
_normalize: function (items) {
// assume all items have the right format when the first item is complete
if (items.length && items[0].label && items[0].value) {
return items;
}
return $.map(items, function (item) {
if (typeof item === "string") {
return {
label: item,
value: item
};
}
return $.extend({
label: item.label || item.value,
value: item.value || item.label
}, item);
});
},
_suggest: function (items) {
var ul = this.menu.element
.empty()
.zIndex(this.element.zIndex() + 1),
menuWidth,
textWidth;
this._renderMenu(ul, items);
// TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
this.menu.deactivate();
this.menu.refresh();
this.menu.element.show().position($.extend({
of: this.element
}, this.options.position));
menuWidth = ul.width("").outerWidth();
textWidth = this.element.outerWidth();
ul.outerWidth(Math.max(menuWidth, textWidth));
},
_renderMenu: function (ul, items) {
var self = this;
$.each(items, function (index, item) {
self._renderItem(ul, item);
});
},
_renderItem: function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append($("<a></a>").text(item.label))
.appendTo(ul);
},
_move: function (direction, event) {
if (!this.menu.element.is(":visible")) {
this.search(null, event);
return;
}
if (this.menu.first() && /^previous/.test(direction) ||
this.menu.last() && /^next/.test(direction)) {
this.element.val(this.term);
this.menu.deactivate();
return;
}
this.menu[direction](event);
},
widget: function () {
return this.menu.element;
}
});
$.extend($.ui.autocomplete, {
escapeRegex: function (value) {
return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
},
filter: function (array, term) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(term), "i");
return $.grep(array, function (value) {
return matcher.test(value.label || value.value || value);
});
}
});
} (jQuery));
Yes, that bug ticket you linked to shows the changeset you need to follow.
Notice how instead of saying $('selector').autocomplete(...) you're expected to do:
$('selector').bind('keydown', function (event) {
if (event.keyCode === $.ui.keyCode.TAB &&
$(this).data('autocomplete').menu.active ) {
event.preventDefault();
}
}).autocomplete(...)
Notice that you're intercepting TAB keydowns if the menu is "active" and preventing the event from doing the default behavior, which in a browser is focusing the next statically laid out element.

Using function as a param in a controller

OK, I have a controller where I need to use a function as a param
angular.module('myCtrl', function($scope) {
$scope.$on('lines:deselectLine', function(ev, slip) {
_.each($scope.lineItems, function(lineItem) {
_.each(lineItem, function(lineLeague) {
_.each(lineLeague, function(line) {
_.each(line.rows, function(row) {
if (row.nss + '' === slip.nss) {
var line = slip.line;
if (line === row.spread.line + '') {
row.spreadSelected = false;
}
if (line === row.total.line + '') {
row.totalSelected = false;
}
if (line === row.moneyLineId + '') {
row.moneyLineSelected = false;
}
}
});
});
});
});
});
});
this is the full function but I need to take this part away in a function
if (row.nss + '' === slip.nss) {
var line = slip.line;
if (line === row.spread.line + '') {
row.spreadSelected = false;
}
if (line === row.total.line + '') {
row.totalSelected = false;
}
if (line === row.moneyLineId + '') {
row.moneyLineSelected = false;
}
}
so at the end I will need something like this
angular.module('myCtrl', function($scope) {
$scope.$on('lines:deselectLine', function(ev, slip) {
_.each($scope.lineItems, function(lineItem) {
_.each(lineItem, function(lineLeague) {
_.each(lineLeague, function(line) {
_.each(line.rows, function(row, iWillBeFunctionParam) {
//SOMETHING NEW WILL HAPPEN HERE
});
});
});
});
});
$scope.iWillBeFunctionParam = function(slip) {
if (row.nss + '' === slip.nss) {
var line = slip.line;
if (line === row.spread.line + '') {
row.spreadSelected = false;
}
if (line === row.total.line + '') {
row.totalSelected = false;
}
if (line === row.moneyLineId + '') {
row.moneyLineSelected = false;
}
}
};
});
Be aware of the $scope.$on which is an $emit...
So, what should I do to use the new function as a Param ?
It's doesn't look like you need to pass a function as a parameter to the controller, so your title is somewhat confusing.
It seems that you want to invoke some function in the innermost _.each. Perhaps I'm misunderstanding your intent, but I don't see any place where this iWillBeFunctionParam is needed to be passed as a parameter to anything.
So, you have the following - whether in a controller or not, not relevant - conceptually speaking:
var lines = [[], [], []]; // array of arrays
$scope.$on("foo", function(ev, slip){
_.each(lines, function(line){
_.each(line.rows, function(row){
doSomethingWith(slip, line, row);
})
})
})
Then you can define your doSomethingWith function accordingly:
function doSomethingWith(slip, line, row){
// etc...
}

how to add submit function to js Onclick function [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
i am trying to trigger a url when click on a button, when click on the delete button it triggers the JS Alert but it is not passing the link, it removes the button instead. how can make it process the link once i confirm the alert?
js code
<script>
$(function() {
$('#demo').confirmOn('click', function() {
$(this).remove();
});
});
</script>
html
<a href="index.php?page=test:delete&item_id={item_id}" id="demo">
<input type="button" class="log_button" value="Delete"/>
ConfirmOn code..
(function($) {
var confirmOn = $.confirmOn = {};
confirmOn.providedOptions = {};
confirmOn.defaultSettings = {
questionText: 'Are you sure?',
classPrepend: 'confirmon',
textYes: 'Yes',
textNo: 'No'
};
confirmOn.overrideDefaultSettings = function(settings) {
confirmOn.defaultSettings = $.extend({}, confirmOn.defaultSettings, settings);
};
confirmOn.setOptions = function($element, options) {
options = $.extend({}, confirmOn.defaultSettings, options);
$element.data('confirmon', {
options: options
});
};
confirmOn.createOverlay = function($element) {
var classPrepend = $element.data('confirmon').options.classPrepend;
return $('<div/>').addClass(classPrepend + '-overlay').hide().appendTo('body');
};
confirmOn.showOverlay = function($element) {
var classPrepend = $element.data('confirmon').options.classPrepend;
$('.' + classPrepend + '-overlay').fadeIn();
};
confirmOn.deleteOverlay = function($element) {
var classPrepend = $element.data('confirmon').options.classPrepend;
$('.' + classPrepend + '-overlay').fadeOut(function(){
$(this).remove();
});
};
confirmOn.createBox = function($element) {
var classPrepend = $element.data('confirmon').options.classPrepend;
var questionText = $element.data('confirmon').options.questionText;
var textYes = $element.data('confirmon').options.textYes;
var textNo = $element.data('confirmon').options.textNo;
var $box = $('<div/>').addClass(classPrepend + '-box').hide().appendTo('body');
$('<p class="' + classPrepend + '-content"/>')
.html(questionText)
.appendTo($box);
$('<button class="' + classPrepend + '-button ' + classPrepend + '-button--yes"/>')
.html(textYes)
.appendTo($box);
$('<button class="' + classPrepend + '-button ' + classPrepend + '-button--no"/>')
.html(textNo)
.appendTo($box);
$('.' + classPrepend + '-button').on('keydown', function(e){
if (e.which === 9) { //Tab key
e.preventDefault();
$('.' + classPrepend + '-button').not(this).focus();
}
});
};
confirmOn.showBoxAndFocusNo = function($element) {
var classPrepend = $element.data('confirmon').options.classPrepend;
$('.' + classPrepend + '-box').fadeIn(function(){
$(this).children('button').eq(1).focus();
});
};
confirmOn.deleteBox = function($element) {
var classPrepend = $element.data('confirmon').options.classPrepend;
$('.' + classPrepend + '-box').fadeOut(function(){
$(this).remove();
});
};
$.confirmOn.handleEscKey = function($element) {
$(document).on('keydown.confirmon.close', function(e){
if (e.which === 27) { //Esc key
$.confirmOn.deleteOverlay($element);
$.confirmOn.deleteBox($element);
$(document).off('keydown.confirmon.close');
}
});
}
confirmOn.convertArguments = function(options, events, selector, data, handler) {
if (typeof options === 'object') {
$.each(options, function(key, val) {
if (typeof val === 'string') { //Options provided so shift all args to left
confirmOn.providedOptions = options;
options = events;
events = selector;
selector = data;
data = handler;
return false;
} else { //No options
confirmOn.providedOptions = {};
}
});
} else {
confirmOn.providedOptions = {};
}
if (selector == null && data == null && handler == null) {
//(events[S], handler)
selector = events;
events = options;
} else if (data == null && handler == null) {
//(events[S], selector, handler)
//(events[S], data, handler)
data = selector;
selector = events;
events = options;
} else {
handler = data;
data = selector;
selector = events;
events = options;
}
if (typeof events === 'object') {
//Implementation .on( events [, selector ] [, data ] )
return {
events: events,
selector: selector,
data: data
};
} else {
//Implementation .on( events [, selector ] [, data ], handler(eventObject) )
return {
events: events,
selector: selector,
data: data,
handler: handler
};
}
};
$.confirmOn.attachHandlers = function($element, handler, event) {
var classPrepend = $element.data('confirmon').options.classPrepend;
$('.' + classPrepend + '-box button').eq(0).on('click', function(){
$.confirmOn.deleteOverlay($element);
$.confirmOn.deleteBox($element);
handler.call($element.get(), event, true); //Call the handler function. the TRUE parameter indicates that the user pressed the YES button
});
$('.' + classPrepend + '-box button').eq(1).on('click', function(){
$.confirmOn.deleteOverlay($element);
$.confirmOn.deleteBox($element);
handler.call($element.get(), event, false); //Call the handler function. the FALSE parameter indicates that the user pressed the YES button
});
};
$.fn.confirmOn = function(options, events, selector, data, handler) {
var userHandler;
if (typeof events === 'function') {
userHandler = events;
events = confirmHandler;
} else if (typeof selector === 'function') {
userHandler = selector;
selector = confirmHandler;
} else if (typeof data === 'function') {
userHandler = data;
data = confirmHandler;
} else if (typeof handler === 'function') {
userHandler = handler;
handler = confirmHandler;
}
var $element = $(this);
var onArgs = $.confirmOn.convertArguments(options, events, selector, data, handler);
$.confirmOn.setOptions($element, $.confirmOn.providedOptions);
$element.on(onArgs.events, onArgs.selector, onArgs.data, onArgs.handler);
function confirmHandler(event) {
event.preventDefault();
$.confirmOn.createOverlay($element);
$.confirmOn.showOverlay($element);
$.confirmOn.createBox($element);
$.confirmOn.showBoxAndFocusNo($element);
$.confirmOn.handleEscKey($element);
$.confirmOn.attachHandlers($element, userHandler, event);
};
};
}(jQuery));
Use confirm():
Try this:
$("#demo").click(function() {
var confirm1 = confirm('Dialogue');
if (confirm1) {
$(this).remove();
return true;
} else {
return false;
}
});
UPDATE
$(function () {
$('#demo').confirmOn('click', function (e, confirmed) {
if (confirmed) { // Clicked yes
document.location.href= $(this).attr('href');
$(this).remove();
$('#msg_button_1').remove();
} else { // Clicked no
$('#msg_button_1').fadeIn();
}
});
});
JSFiddle Demo
Edited
<script>
$(function() {
$('.log_button').confirmOn('click', function(e, confirmed) {
if(confirmed){
//$('#demo').remove();
$('#demo').click();
}else{
alert("not go");
}
});
});
</script>
is this the thing that you actually want to do? click the button and then go to the link?

iCheck doesn't work ( strange behavior )

I want to use iCheck library:
https://github.com/fronteed/iCheck
http://fronteed.com/iCheck/
When i init the element with the library it get warped like the documentation describe https://github.com/fronteed/iCheck/#how-it-works but with opacity zero.
You can see it here: http://jsfiddle.net/buRq7/8/
$(".ex-f").iCheck();
somebody have the same issue?
Thanks
My code is:
/*!
* iCheck v1.0.1, http://git.io/arlzeA
* =================================
* Powerful jQuery and Zepto plugin for checkboxes and radio buttons customization
*
* (c) 2013 Damir Sultanov, http://fronteed.com
* MIT Licensed
*/
(function($) {
// Cached vars
var _iCheck = 'iCheck',
_iCheckHelper = _iCheck + '-helper',
_checkbox = 'checkbox',
_radio = 'radio',
_checked = 'checked',
_unchecked = 'un' + _checked,
_disabled = 'disabled',
_determinate = 'determinate',
_indeterminate = 'in' + _determinate,
_update = 'update',
_type = 'type',
_click = 'click',
_touch = 'touchbegin.i touchend.i',
_add = 'addClass',
_remove = 'removeClass',
_callback = 'trigger',
_label = 'label',
_cursor = 'cursor',
_mobile = /ipad|iphone|ipod|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent);
// Plugin init
$.fn[_iCheck] = function(options, fire) {
// Walker
var handle = 'input[type="' + _checkbox + '"], input[type="' + _radio + '"]',
stack = $(),
walker = function(object) {
object.each(function() {
var self = $(this);
if (self.is(handle)) {
stack = stack.add(self);
} else {
stack = stack.add(self.find(handle));
};
});
};
// Check if we should operate with some method
if (/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(options)) {
// Normalize method's name
options = options.toLowerCase();
// Find checkboxes and radio buttons
walker(this);
return stack.each(function() {
var self = $(this);
if (options == 'destroy') {
tidy(self, 'ifDestroyed');
} else {
operate(self, true, options);
};
// Fire method's callback
if ($.isFunction(fire)) {
fire();
};
});
// Customization
} else if (typeof options == 'object' || !options) {
// Check if any options were passed
var settings = $.extend({
checkedClass: _checked,
disabledClass: _disabled,
indeterminateClass: _indeterminate,
labelHover: true,
aria: false
}, options),
selector = settings.handle,
hoverClass = settings.hoverClass || 'hover',
focusClass = settings.focusClass || 'focus',
activeClass = settings.activeClass || 'active',
labelHover = !!settings.labelHover,
labelHoverClass = settings.labelHoverClass || 'hover',
// Setup clickable area
area = ('' + settings.increaseArea).replace('%', '') | 0;
// Selector limit
if (selector == _checkbox || selector == _radio) {
handle = 'input[type="' + selector + '"]';
};
// Clickable area limit
if (area < -50) {
area = -50;
};
// Walk around the selector
walker(this);
return stack.each(function() {
var self = $(this);
// If already customized
tidy(self);
var node = this,
id = node.id,
// Layer styles
offset = -area + '%',
size = 100 + (area * 2) + '%',
layer = {
position: 'absolute',
top: offset,
left: offset,
display: 'block',
width: size,
height: size,
margin: 0,
padding: 0,
background: '#fff',
border: 0,
opacity: 0
},
// Choose how to hide input
hide = _mobile ? {
position: 'absolute',
visibility: 'hidden'
} : area ? layer : {
position: 'absolute',
opacity: 0
},
// Get proper class
className = node[_type] == _checkbox ? settings.checkboxClass || 'i' + _checkbox : settings.radioClass || 'i' + _radio,
// Find assigned labels
label = $(_label + '[for="' + id + '"]').add(self.closest(_label)),
// Check ARIA option
aria = !!settings.aria,
// Set ARIA placeholder
ariaID = _iCheck + '-' + Math.random().toString(36).replace('0.', ''),
// Parent & helper
parent = '<div class="' + className + '" ' + (aria ? 'role="' + node[_type] + '" ' : ''),
helper;
// Set ARIA "labelledby"
if (label.length && aria) {
label.each(function() {
parent += 'aria-labelledby="';
if (this.id) {
parent += this.id;
} else {
this.id = ariaID;
parent += ariaID;
}
parent += '"';
});
};
// Wrap input
parent = self.wrap(parent + '/>')[_callback]('ifCreated').parent().append(settings.insert);
// Layer addition
helper = $('<ins class="' + _iCheckHelper + '"/>').css(layer).appendTo(parent);
// Finalize customization
self.data(_iCheck, {o: settings, s: self.attr('style')}).css(hide);
!!settings.inheritClass && parent[_add](node.className || '');
!!settings.inheritID && id && parent.attr('id', _iCheck + '-' + id);
parent.css('position') == 'static' && parent.css('position', 'relative');
operate(self, true, _update);
// Label events
if (label.length) {
label.on(_click + '.i mouseover.i mouseout.i ' + _touch, function(event) {
var type = event[_type],
item = $(this);
// Do nothing if input is disabled
if (!node[_disabled]) {
// Click
if (type == _click) {
if ($(event.target).is('a')) {
return;
}
operate(self, false, true);
// Hover state
} else if (labelHover) {
// mouseout|touchend
if (/ut|nd/.test(type)) {
parent[_remove](hoverClass);
item[_remove](labelHoverClass);
} else {
parent[_add](hoverClass);
item[_add](labelHoverClass);
};
};
if (_mobile) {
event.stopPropagation();
} else {
return false;
};
};
});
};
// Input events
self.on(_click + '.i focus.i blur.i keyup.i keydown.i keypress.i', function(event) {
var type = event[_type],
key = event.keyCode;
// Click
if (type == _click) {
return false;
// Keydown
} else if (type == 'keydown' && key == 32) {
if (!(node[_type] == _radio && node[_checked])) {
if (node[_checked]) {
off(self, _checked);
} else {
on(self, _checked);
};
};
return false;
// Keyup
} else if (type == 'keyup' && node[_type] == _radio) {
!node[_checked] && on(self, _checked);
// Focus/blur
} else if (/us|ur/.test(type)) {
parent[type == 'blur' ? _remove : _add](focusClass);
};
});
// Helper events
helper.on(_click + ' mousedown mouseup mouseover mouseout ' + _touch, function(event) {
var type = event[_type],
// mousedown|mouseup
toggle = /wn|up/.test(type) ? activeClass : hoverClass;
// Do nothing if input is disabled
if (!node[_disabled]) {
// Click
if (type == _click) {
operate(self, false, true);
// Active and hover states
} else {
// State is on
if (/wn|er|in/.test(type)) {
// mousedown|mouseover|touchbegin
parent[_add](toggle);
// State is off
} else {
parent[_remove](toggle + ' ' + activeClass);
};
// Label hover
if (label.length && labelHover && toggle == hoverClass) {
// mouseout|touchend
label[/ut|nd/.test(type) ? _remove : _add](labelHoverClass);
};
};
if (_mobile) {
event.stopPropagation();
} else {
return false;
};
};
});
});
} else {
return this;
};
};
// Do something with inputs
function operate(input, direct, method) {
var node = input[0],
state = /er/.test(method) ? _indeterminate : /bl/.test(method) ? _disabled : _checked,
active = method == _update ? {
checked: node[_checked],
disabled: node[_disabled],
indeterminate: input.attr(_indeterminate) == 'true' || input.attr(_determinate) == 'false'
} : node[state];
// Check, disable or indeterminate
if (/^(ch|di|in)/.test(method) && !active) {
on(input, state);
// Uncheck, enable or determinate
} else if (/^(un|en|de)/.test(method) && active) {
off(input, state);
// Update
} else if (method == _update) {
// Handle states
for (var state in active) {
if (active[state]) {
on(input, state, true);
} else {
off(input, state, true);
};
};
} else if (!direct || method == 'toggle') {
// Helper or label was clicked
if (!direct) {
input[_callback]('ifClicked');
};
// Toggle checked state
if (active) {
if (node[_type] !== _radio) {
off(input, state);
};
} else {
on(input, state);
};
};
};
// Add checked, disabled or indeterminate state
function on(input, state, keep) {
var node = input[0],
parent = input.parent(),
checked = state == _checked,
indeterminate = state == _indeterminate,
disabled = state == _disabled,
callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
regular = option(input, callback + capitalize(node[_type])),
specific = option(input, state + capitalize(node[_type]));
// Prevent unnecessary actions
if (node[state] !== true) {
// Toggle assigned radio buttons
if (!keep && state == _checked && node[_type] == _radio && node.name) {
var form = input.closest('form'),
inputs = 'input[name="' + node.name + '"]';
inputs = form.length ? form.find(inputs) : $(inputs);
inputs.each(function() {
if (this !== node && $(this).data(_iCheck)) {
off($(this), state);
};
});
};
// Indeterminate state
if (indeterminate) {
// Add indeterminate state
node[state] = true;
// Remove checked state
if (node[_checked]) {
off(input, _checked, 'force');
};
// Checked or disabled state
} else {
// Add checked or disabled state
if (!keep) {
node[state] = true;
};
// Remove indeterminate state
if (checked && node[_indeterminate]) {
off(input, _indeterminate, false);
};
};
// Trigger callbacks
callbacks(input, checked, state, keep);
};
// Add proper cursor
if (node[_disabled] && !!option(input, _cursor, true)) {
parent.find('.' + _iCheckHelper).css(_cursor, 'default');
};
// Add state class
parent[_add](specific || option(input, state) || '');
// Set ARIA attribute
disabled ? parent.attr('aria-disabled', 'true') : parent.attr('aria-checked', indeterminate ? 'mixed' : 'true');
// Remove regular state class
parent[_remove](regular || option(input, callback) || '');
};
// Remove checked, disabled or indeterminate state
function off(input, state, keep) {
var node = input[0],
parent = input.parent(),
checked = state == _checked,
indeterminate = state == _indeterminate,
disabled = state == _disabled,
callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
regular = option(input, callback + capitalize(node[_type])),
specific = option(input, state + capitalize(node[_type]));
// Prevent unnecessary actions
if (node[state] !== false) {
// Toggle state
if (indeterminate || !keep || keep == 'force') {
node[state] = false;
};
// Trigger callbacks
callbacks(input, checked, callback, keep);
};
// Add proper cursor
if (!node[_disabled] && !!option(input, _cursor, true)) {
parent.find('.' + _iCheckHelper).css(_cursor, 'pointer');
};
// Remove state class
parent[_remove](specific || option(input, state) || '');
// Set ARIA attribute
disabled ? parent.attr('aria-disabled', 'false') : parent.attr('aria-checked', 'false');
// Add regular state class
parent[_add](regular || option(input, callback) || '');
};
// Remove all traces
function tidy(input, callback) {
if (input.data(_iCheck)) {
// Remove everything except input
input.parent().html(input.attr('style', input.data(_iCheck).s || ''));
// Callback
if (callback) {
input[_callback](callback);
};
// Unbind events
input.off('.i').unwrap();
$(_label + '[for="' + input[0].id + '"]').add(input.closest(_label)).off('.i');
};
};
// Get some option
function option(input, state, regular) {
if (input.data(_iCheck)) {
return input.data(_iCheck).o[state + (regular ? '' : 'Class')];
};
};
// Capitalize some string
function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
};
// Executable handlers
function callbacks(input, checked, callback, keep) {
if (!keep) {
if (checked) {
input[_callback]('ifToggled');
};
input[_callback]('ifChanged')[_callback]('if' + capitalize(callback));
};
};
})(window.jQuery || window.Zepto);
$(".ex-f").iCheck();
And
<div class="my-checkbox">
<input class="ex-f" id="Finish" name="Finish" type="checkbox" value="1"> doesn't work
</div>
And
.my-checkbox {
border: 1px solid blue;
height: 20px;
}
.ex-f {
border: 1px solid red;
}
I found that the problem was with the CSS file, if it is not loaded the component is not showed, a working example:
http://jsfiddle.net/SUTMf/1/
$(document).ready(function(){
$('input').iCheck({
checkboxClass: 'icheckbox_flat-blue',
radioClass: 'iradio_square',
increaseArea: '20%' // optional
});
});
today i encountered this problem. and the same problem.
but finally solved.
and the reason is:
my local golobal variable name is "_type" which maybe the keyword in iCheck or somethin' else .
when i have iCheck in my Html, i found that _type is already used as the picture showed
wish could help u and the others.
If you place it before the iCheck code, it works for me:
$(".ex-f").iCheck();
//iCheck function
Demo
Well, same thing happened to me, and the problem was a conflict with other javascript code included in the page. I removed it or changed it and it worked. I hope this could help somebody, I don't put the code in here because could be anything, just check your code just in case same thing is happening to you.

using Javascript within Google Analytics event tracking code to automate category naming

So I'm attempting to implement some google analytics event tracking on dynamically generated pages. I'll be using something like
<script>
$(document).ready(function(){
$("#button1").click(function(){
_gaq.push(['_trackEvent', category, action, opt_label, opt_value, opt_noninteraction)']);
});
$("#button2").click(function(){
_gaq.push(['_trackEvent', category, action, opt_label, opt_value, opt_noninteraction']);
});
});
</script>
I'm wondering is it possible to use something like document.title to auto generate the category section of the GA code from the html title of the pages? All the pages use unique titles and it would be great if the events tracked on those pages could show up in GA as separate entries and not just category.
That was tougher than I expected it. Hope it helps.
Live demo with examples
javascript
// Unbind default behaviour
$(document).off("ready.ga").on("ready", function () {
//hollow out
pageLoc = $(location).attr('href');
// Introduce helper functions.
(function ($, window, undef) {
// ga selector.
$.extend($.expr[":"], {
ga: function (a) {
var attr = a.attributes,
len = attr.length;
while (len--) {
if (attr[len].name.indexOf("data-ga-") !== -1) {
return true;
}
}
return false;
}
});
$.gaaApi = {
trackEvent: {
event: {
value: "_trackEvent",
validation: "isString",
type: "string"
},
category: {
value: null,
validation: "optString",
type: "currentloc"
},
action: {
value: null,
validation: "optString",
type: "string"
},
label: {
value: null,
validation: "optString",
type: "string"
},
value: {
value: null,
validation: "optInt",
type: "integer"
},
nonInteraction: {
value: null,
validation: "optBool",
type: "boolean"
}
},
trackPageview: {
event: {
value: ["trackPageview", $(location).attr('href')],
validation: "isString",
type: "string"
},
url: {
value: undef,
validation: "optString",
type: "string"
}
}
};
var validation = {
isString: function (obj) {
var empty = true;
if (obj && typeof obj === "string") {
empty = /^\s*$/.test(obj);
}
// If empty === true then something is wrong and we should return false.
return !(empty);
},
optString: function (obj) {
if (obj === undef) {
return true;
}
return validation.isString(obj);
},
isInt: function (obj) {
return (/^[\-+]?\d+$/).test(obj) || (obj === +obj && obj === (obj | 0));
},
optInt: function (obj) {
if (obj === undef) {
return true;
}
return validation.isInt(obj);
},
isFloat: function (obj) {
return (/^[\-+]?\d+(\.\d+)?$/).test(obj) || (obj === +obj && obj !== (obj | 0));
},
optFloat: function (obj) {
if (obj === undef) {
return true;
}
return validation.isFloat(obj);
},
isBool: function (obj) {
return (obj === true || obj === "true") || (obj === false || obj === "false");
},
optBool: function (obj) {
if (obj === undef) {
return true;
}
return validation.isBool(obj);
}
},
methods = {
validate: function (param, name, location) {
var $element = this.$element,
data = $element.data("ga-" + name.toLowerCase()),
isValid;
//pageLoc = $(location).attr('href');
if (!validation[param.validation]) {
throw new TypeError("Unknown validation type");
}
// Check the value.
isValid = validation[param.validation](data);
if (!isValid) {
throw new Error("object validation error on " + name);
}
// Assign the value.
// Some analytics methods accept numbers as strings so we check the return type.
switch (param.type) {
case "integer":
return data ? parseInt(data, 10) : null;
case "float":
return data ? parseFloat(data) : null;
case "boolean":
return data ? Boolean(data) : null;
case "currentloc":
return data;
default:
// Default to string.
return data ? data + "" : null;
}
},
createArgs: function () {
var binder = this,
event = this.event,
args = $.map(event, function (val, key, pageLoc) {
var pageLoc = $(location).attr('href');
var value;
if (key === "event") {
// We don't want to check for the event property in the DOM.
value = val.value;
} else {
// Validate and return the correct value from the DOM.
value = methods.validate.call(binder, val, key, pageLoc);
}
return value;
});
return args;
}
},
gaa = function (element, options) {
this.$element = $(element);
this.options = $.extend({}, $.fn.gaa.defaults, options);
};
gaa.prototype = {
constructor: gaa,
trackEvent: function () {
var trackedEvent = $.Event("tracked.ga");
var currentLoc = $(location).attr('href');
this.args = methods.createArgs.call(this);
if (this.options.logit) {
if (window.console && window.console.log) {
// Push the data.
console.log("pushing to Google analytics", this.args);
this.$element.trigger(trackedEvent).trigger(currentLoc);
// this.$element.trigger(currentLocation);
}
} else {
var gaq = window._gaq;
if (gaq) {
// Set the context for our deferred callback.
var binder = this;
// Push the data.
$.when(gaq.push(args)).done(
function () {
this.$element.trigger(trackedEvent);
// this.$element.trigger(trackedEvent);
// Redirect the location - delayed so that any other page functionality has time to run.
setTimeout(function () {
var href = binder.attr("href");
if (href && href.indexOf("#") !== 0) {
window.location = href;
}
}, 100);
});
} else {
throw new ReferenceError(" _gaq not there");
}
}
}
};
// wrapper definition
$.fn.gaa = function (options) {
return this.each(function () {
var $this = $(this),
data = $this.data("ga"),
opts = typeof options === "object" ? options : null;
if (!data) {
// Check the data and assign if not present.
$this.data("ga", (data = new gaa(this, opts)));
}
// Run the appropriate function is a string is passed.
if (typeof options === "string") {
data[options]();
} else {
var handler = data.options.handler.toLowerCase(),
// Check for the event attr here as it might be other than the default.
event = data.$element.attr("data-ga-event");
// Overwrite if necessary.
$.extend(data.options, {
event: event
});
// Build the data as we have nothing there.
// First assign the event.
data.event = $.gaaApi[data.options.event];
// Then bind the handler.
if (handler === "load") {
data.trackEvent();
} else {
data.$element.on(handler + ".ga", function (e) {
e.preventDefault();
data.trackEvent();
});
}
}
});
};
// Define the defaults.
$.fn.gaa.defaults = {
event: ["trackEvent", "giveLocation"],
handler: "load",
logit: false
};
// Set the public constructor.
$.fn.gaa.Constructor = gaa;
// Let's BEGIN
$(document).on("ready.ga", function () {
// Bind using the custom selector.
$(":ga").each(function () {
$(this).gaa();
});
});
}(jQuery, window));
// Set some options the ones below are the defaults.
var options = {
event: "trackEvent", // The event name unprefixed.
handler: "click", // The eventhandler to trigger the tracking.
// Using 'load' will track immediately.
logit: true, //to logit
};
var options2 = {
event: "trackPageview", // The event name unprefixed.
handler: "click", // The eventhandler to trigger the tracking.
// Using 'load' will track immediately.
logit: true, //to logit
};
var options3 = {
event: "trackPageview", // The event name unprefixed.
handler: "load", // The eventhandler to trigger the tracking.
// Using 'load' will track immediately.
logit: true //to logit
};
// Binds using the custom selector.
$("load.trigger").gaa(options3); //fires a ga onload after domready
$("button.button1").gaa(options2).click(function () {
console.log('\nmore button events\n', 'heres the URL:', location.href)
});
$("#clickme").gaa(options).click(function () {
$(this).toggleClass("changeIt");
});
});
index.html
<load class="trigger">loading triggers ga event</load>
<button class="button1">fire ga event with address</button>
<button class="button1" id="clickme">multiple events</button>
The location bind happens here and lets jquery consume location properly.
event: {
value: ["trackPageview",$(location).attr('href')],
validation: "isString",
type: "string"
}
your approach of using this was correct but you had to get the location earlier to get it into ga. It seems like anyways this format
$("#button").gaa(options).click(function () {
$(this).toggleClass("changeIt");
});
Will get you going in the right directions.
This was a fun brainache. That should give you access to location.href where you want need it later on. The idea is to form a bind after DOM ready but before _gaq execution.

Categories