I am confused with this particular ajax object - javascript

I recently learned a few ajax methods in jQuery and I stumbled upon this code and I cannot figure out what it's doing.
ajax: {
init: function() {
app.ajax._ctr = 1;
app.ajax._preloaded = {};
app.ajax.inProgress = false;
app.dom.$body.on('click', 'a:not(.no-ajax):not([hreflang])', function(e) {
var $a = $(e.currentTarget);
var href = $a.attr('href');
// what is indexOf
if (href.indexOf('mailto:') < 0
&& href != '#'
&& ((href.indexOf(app.baseUrl) >= 0 && href.indexOf(app.baseUrl) <= 7) || href.indexOf('://') < 0)
&& !$a.parents('.mejs-container').length) {
e.preventDefault();
app.ajax.loadPage(href, true, $a.attr('data-ajax-resolver'));
}
});
// below is load event
app.dom.$window.on('load', function() {
app.ajax.currentStateCtr = app.ajax._ctr;
history.replaceState({ internal: true, ctr: app.ajax._ctr++ }, null, document.URL);
});
// below is popstate event
app.dom.$window.on('popstate', function(e) {
if (e.originalEvent.state && e.originalEvent.state.internal) {
app.ajax.loadPage(location.href, false, null, e.originalEvent.state.ctr < app.ajax.currentStateCtr);
app.ajax.currentStateCtr = e.originalEvent.state.ctr;
}
});
}, // end of init
getResolver: function(resolverName) {
if (resolverName !== undefined && app.ajax._resolvers[resolverName] !== undefined) {
return app.ajax._resolvers[resolverName];
}
return app.ajax._defaultResolver;
},
I notice that it declares it within an App object with an empty DOM object. I also understand there are a few jQuery events being used here, but I don't understand exactly how the 'popstate' event and the getResolver function is being used with data.

Related

reset autocomplete field text by clicking outside vue

I have an autocomplete field. If i put any text and it matches the result set then it will populate the dropdown result. If it doesn’t match anything then by clicking outside it will reset the input field forcefully.
So, for this approach i have created the vue click outside directive
import Vue from 'vue';
const nodeList = [];
const ctx = '##clickoutsideContext';
let startClick;
const counter = 0;
const isServer = Vue.prototype.$isServer;
/**
* added this on event function for direct dom manipulation
*/
const onEvent = (function() {
if (!isServer && document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
};
}
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent(`on${event}`, handler);
}
};
})();
!isServer &&
onEvent(document, 'mousedown', e => {
startClick = e;
});
!isServer &&
onEvent(document, 'mouseup', e => {
nodeList.forEach(node => node[ctx].documentHandler(e, startClick));
});
// setting up mouse events
function createDocumentHandler(el, binding, vnode) {
return function(mouseup = {}, mousedown = {}) {
if (
!vnode ||
!vnode.context ||
!mouseup.target ||
!mousedown.target ||
el.contains(mouseup.target) ||
el.contains(mousedown.target) ||
el === mouseup.target ||
(vnode.context.popperElm &&
(vnode.context.popperElm.contains(mouseup.target) ||
vnode.context.popperElm.contains(mousedown.target)))
)
return;
if (
binding.expression &&
el[ctx].methodName &&
vnode.context[el[ctx].methodName]
) {
vnode.context[el[ctx].methodName]();
} else {
el[ctx].bindingFn && el[ctx].bindingFn();
}
};
}
/**
* v-clickoutside
* #desc Only trigger when click outside
* #example
* ```vue
* <div v-element-clickoutside="handleClose">
* ```
*/
export default {
bind(el, binding, vnode) {
nodeList.push(el);
const id = counter + 1;
el[ctx] = {
id,
documentHandler: createDocumentHandler(el, binding, vnode),
methodName: binding.expression,
bindingFn: binding.value
};
},
update(el, binding, vnode) {
el[ctx].documentHandler = createDocumentHandler(el, binding, vnode);
el[ctx].methodName = binding.expression;
el[ctx].bindingFn = binding.value;
},
unbind(el) {
const len = nodeList.length;
for (let i = 0; i < len; i += 1) {
if (nodeList[i][ctx].id === el[ctx].id) {
nodeList.splice(i, 1);
break;
}
}
delete el[ctx];
}
};
Here is the autocomplete field in forms field
<div v-if="field.type == 'autocomplete'">
<vu-auto-complete
v-model="fieldvalues[field.key]"
:items="formFieldAutocompleteItems[fieldvalues[field.key]] || []"
:label="labelrequired(field)"
:placeholder="field.placeholder"
:error-message="errorMsg[field.key]"
#input="handleOnInput($event, field)"
#selected="getSelectedData($event, field)"
>
</vu-auto-complete>
</div>
methods for handleOnInput
handleOnInput(inputKey, field) {
if (inputKey !== null && inputKey.length >= 3) {
this.fieldvalues = {
...this.fieldvalues,
[field.key]: inputKey
};
const data = {
url: field.autocompleteUri,
search: field.autocompleteUriKey,
text: inputKey,
key: field.key
};
clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.$emit('autocompleteInput', data);
}, 500);
} else if (inputKey.length === 0 || inputKey === null) {
const formData = { ...this.fieldvalues };
if (field.dependentFields && field.dependentFields.length > 0) {
for (let i = 0; i < field.dependentFields.length; i += 1) {
formData[field.dependentFields[i]] = '';
}
}
this.fieldvalues = formData;
}
},
Autocomplete field is working fine. So, i need directive or methods to reset any input by clicking outside.
Any suggestions or examples will be helpful to understand.
I'd suggest you use the onClickOutside utility from VueUse.
VueUse is effectively a collection of super useful utility functions for Vue with support for Vue2, Vue3 and Typescript.
There's over 90 different utilities for so many different use cases and the library is treeshakable so you only have to bundle what you use.
The onClickOutside utility expects a target ref and a callback along with an optional third param for configuration.
Something like this should work for you:
onClickOutside(
inputRef,
(event) => {
console.log(event);
this.inputText = '';
},
{ event: 'mousedown' },
)
This saves you the time of writing custom code where you may miss out on important considerations such as accessibility. If you want, you can dig into the source of the utility and explore how it works internally.

IE11 Javascript error undefined null reference

I have a javascript error raised in IE11 that is disabling scrolling by mouse on the page. I'd like to know what the problem is with the code and if it can easily be modified to fix it.
The error is:
{exception} Unable to get property 'length' of undefined or null reference
It occurs in this block of code, in line 8 as shown handlers is a null reference:
return {
add: function(elem, event, handler) {
if(!elem.events) {
elem.events = {};
elem.handle = function(e) {
var ret, handlers = elem.events[e.type];
e = fixEvent(e);
for(var i = 0, len = handlers.length; i < len; i++) {
if(handlers[i]) {
ret = handlers[i].call(elem, e);
if(ret === false) {
e.preventDefault();
e.stopPropagaton();
}
}
}
};
}
if(!elem.events[event]) {
elem.events[event] = [];
if(elem.addEventListener) elem.addEventListener(event, elem.handle, false);
else if(elem.attachEvent) elem.attachEvent('on'+event, elem.handle);
}
elem.events[event].push(handler);
},
remove: function(elem, event, handler) {
var handlers = elem.events[event];
for(var i = handlers.length - 1; i >= 0; i--) {
if(handlers[i] === handler) {
handlers.splice(i,1);
}
}
if(!handlers.length) {
delete elem.events[event];
if(elem.removeEventListener) elem.removeEventListener(event, elem.handle, false);
else if(elem.detachEvent) elem.detachEvent('on'+event, elem.handle);
}
}
};

Javascript: Check if function is TRUE

i have a function, which should return TRUE, when IF condition inside FOR cyklus is met. (i tested that condition, it works)
createBtn.addEventListener('click',function (e){
var ch = function check(){
var url = "http://hotel.010.sk/skyfit/read.php";
var json, poc, vypis;
var i=0;
var xhr = Ti.Network.createHTTPClient({
onload: function() {
json = JSON.parse(this.responseText);
for (i = 0; i < json.poc.length; i++) {
prnt = json.poc[i];
if(win.xtra_id == prnt.id_cv && picker.getSelectedRow(0).title == prnt.datum && prnt.capacity <= prnt.cnt ){
return true;
}
};
}
});
xhr.open("GET", url);
xhr.send();
};
...
But when i call function here to check it turns me always true, unless IF condition in check() is not met!
if(ch){
alert('Something');
}
How to fix my function to get TRUE only when my condition is met?
Thanks.
This expression
if (ch) {
is always true, because ch is a function and ToBoolean(function) === true.
However even if you changed it to if (ch()) {..} it would not work anyway, because inside of the function you perform asynchronous operation. Function just returns without waiting for it to finish. In this case you should use callbacks or promise patters. Simplest is callback.
var ch = function check(callback) {
// ...
var xhr = Ti.Network.createHTTPClient({
onload: function () {
json = JSON.parse(this.responseText);
var status = false;
for (i = 0; i < json.poc.length; i++) {
prnt = json.poc[i];
if (win.xtra_id == prnt.id_cv && picker.getSelectedRow(0).title == prnt.datum && prnt.capacity <= prnt.cnt) {
status = true;
}
};
callback(status);
}
});
// ...
};
ch(function(status) {
if (status) {
alert('Something')
}
});
Please try with following thing to check condition should always true
while(true){
alert('something');
}
Your function, ch has no return value! It launches the Ti.Network.createHTTPClient function where you define an anonymous callback function (onload: function(){...). That anonymous function is executed after the ch has already returned. You'll need to either check your conditional after the callback:
...
if (win.xtra_id == prnt.id_cv && picker.getSelectedRow(0).title == prnt.datum && prnt.capacity <= prnt.cnt) {
alert('something') //DO YOUR STUFF HERE!
return true;
}
...
or wait for the callback to happen before you check the conditional using some global flags:
var MYFLAG=-1
...
if (win.xtra_id == prnt.id_cv && picker.getSelectedRow(0).title == prnt.datum && prnt.capacity <= prnt.cnt) {
MYFLAG=1
return true;
}
else
{
MYFLAG=0
}
...
//use a timer to check the flag every 500ms
var myInterval = setInterval(function()
{
if (MYFLAG != -1) {
if (MYFLAG==1) {
alert('returned true :)');
}
else {
alert('did not return true :(');
}
clearInterval(myInterval);
}
}, 500);

jQuery Ajax call in an unexpected loop

I'm developing an application where I load content using ajax calls. But in a certain situation, I get an ajax call on a loop but it ends in random iterations. Below is the sequential code from the a double click event to the final ajax call.
//I use the double click event to fire the function
$('.item-container').on('click', '.item', function(e) {
var posX = e.pageX;
var posY = e.pageY;
var element = $(this);
var that = this;
setTimeout(function() {
var dblclick = parseInt($(that).data('double'), 10);
if (dblclick > 0) {
$(that).data('double', dblclick-1);
} else {
showToolTip(posX,posY,element);
}
}, 300);
}).on('dblclick', '.item', function(e) {
$(this).data('double', 2);
addItemsToBill(this);
});
function addItemsToBill(selectedItem) {
var element = null;
$(".bill-item-list").each(function() {
if ($(this).css("display") == "block") {
element = $(this);
return;
}
});
if (element == null) {
getSystemMessage(BILL_SELECT_VALIDATION_MSG);
return;
}
if ($('#open-tab .bill-list').find(".bill-item-list").length == 0
&& $(element).find('.bill-item').length == 0) {
getSystemMessage(BILL_SELECT_VALIDATION_MSG);
return;
}
var bill = $('.sample-elements').find('.bill-item');
var clone = bill.clone();
var itemId = $(selectedItem).attr('id');
var billId = $(element).parent().attr('id');
if ($(selectedItem).attr('isopen') == '1') {
$('.open-item-popup-overlay').lightbox_me( {
centered : true,
destroyOnClose : false,
});
$('.itmRate').val('');
$('#itmAmt').html('0.00');
$('.itemQty').text('1');
$('.itm-cancel').click(function() {
$('.open-item-popup-overlay').trigger('close');
});
//when the first run goes it's fine, bt after that, the looping starts from here. I double checked whether there is another code segment which fires this but there are none.
$('.itm-ok').click(function(){
if ($('.itmRate').val() == "") {
getSystemMessage(AMOUNT_INPUT);
return;
}
//This function gets iterated multiple times if I run the same event for multiple times.
//The function is only used in this two locations and no any other places.
billItemDrop(itemId, billId, clone, selectedItem, null,element, 1, true);
return false;
})
} else {
billItemDrop(itemId, billId, clone, selectedItem, null, element, 0,true);
}
}
function billItemDrop(itemId, billId, billItemClone, doubleClickedItem,draggableHelper, catchElement, isOpen, isDoubleClick) {
var openItemQuantity = stringToDouble($('.itemQty').val());
var openItemRate = stringToDouble($('.itmRate').val());
var openItemAmount = openItemQuantity * openItemRate;
var ajaxObject = 'itemId=' + itemId + '&billId=' + billId + '&qty='
+ openItemQuantity + '&rate=' + openItemRate + '&openItem='
+ isOpen;
ajaxCall(ADD_ITEM_TO_BILL,AJAX_POST,ajaxObject,function(response) {
var responseObject = response.billDetail;
var billTotal = responseObject.billTotal;
var total = response.billDetail.rate * response.billDetail.qty;
// Add Items to the bill failed
if (response.status != "success") {
getSystemMessage(ADD_ITEM_TO_PRINTED_BILL);
return;
}
billItemClone.attr('itemId', responseObject.itemId);
billItemClone.attr('billDetailId', responseObject.billDetailId);
billItemClone.find('.bill-item-name').text(
responseObject.itemName);
billItemClone.find('.bill-item-rate span').text(
responseObject.rate.toFixed(2));
billItemClone.find('.bill-item-amount').text(
total.toFixed(2));
billItemClone.find('.bill-item-qty span').text(responseObject.qty);
if (responseObject.kotBotNo != null) {
billItemClone.find('.kot-bot-num').text(
responseObject.kotBotNo);
}
billItemClone.draggable( {
revert : false,
addClasses : false,
zIndex : 1,
containment : "window",
opacity : 0.5,
cursor : "move",
scroll : false,
helper : function() {
return $(this).clone().appendTo('body').show();
}
});
if (isDoubleClick == true
&& (doubleClickedItem != undefined
|| doubleClickedItem != null || doubelClickedItem != "")) {
billItemClone.find('.bill-item-img img').attr('src',
$(doubleClickedItem).css('background-image'));
} else if (isDoubleClick == false
&& (draggableHelper != undefined
|| drdraggableHelper != null || draggableHelper != "")) {
billItemClone.find('.bill-item-img img').attr('src',
draggableHelper.css('background-image'));
}
if (catchElement.height() > 300) {
catchElement.css('overflow-y', 'scroll');
catchElement.css('height', '320px');
}
if (catchElement.find('.bill-item').length == 0) {
billItemClone.insertBefore(
catchElement.find('.item-drop-point')).hide()
.fadeIn("slow");
} else {
billItemClone.insertBefore(
catchElement.find('.bill-item').first()).hide()
.fadeIn("slow");
}
catchElement.parent().find('.amount')
.html(billTotal.toFixed(2));
if (draggableHelper != undefined || draggableHelper != null) {
draggableHelper.hide('fade', function() {
draggableHelper.remove()
});
}
$('.item-drop-point').removeClass('item-drop-hover');
},false);
}
/**
*
* Function for ajax calls - url : webservice url - type : ajax call type - data :
* data that needs to be passed - callback : function that needs to be executed
*
* when ajax call succeed
*
* #param url
* #param type
* #param data
* #param callback
*/
function ajaxCall(url, type, data, callback,async){
// Assign default value to async if its not specified
if (async===undefined) async = true;
$.ajax({
url: url,
type: type,
data: data,
dataType : "json",
cache: false,
beforeSend: function(x){
if(x && x.overrideMimeType){
x.overrideMimeType("application/json;charset=UTF-8");
}
},
async : async,
success:callback
});
}
The function gets iterated so the ajax call gets iterated too. I used break points to track the iteration but from the point of the click event I couldn't locate where it get's triggered after the first click event.
Is there anything wrong in the code which makes the function iterate. Please help.
Every time you call addItemsToBill(this); you are adding new event handlers to $('.itm-ok')
Try removing the call to billItemDrop(itemId, billId, clone, selectedItem, null,element, 1, true); and replacing it with a console.log('Test' If you find that multiple console logs are being made every time you click the issue is that every click is being handled by multiple handlers. If that is the case and you really want to use this structure you will have to unbind you click handler before rebinding it.
$('.itm-ok').off('click')
$('.itm-ok').on('click',function(){
if ($('.itmRate').val() == "") {
getSystemMessage(AMOUNT_INPUT);
return;
}
//This function gets iterated multiple times if I run the same event for multiple times.
//The function is only used in this two locations and no any other places.
billItemDrop(itemId, billId, clone, selectedItem, null,element, 1, true);
return false;
})

Hide go to top button when page is fully scrolled to the top

I have a button on my wordpress theme homepage that is used for going to the top of the page. I want to hide it when page is fully scrolled to the top. Here is my code:
(function($) {
var version = '#VERSION',
defaults = {
exclude: [],
excludeWithin:[],
offset: 0,
direction: 'top', // one of 'top' or 'left'
scrollElement: null, // jQuery set of elements you wish to scroll (for $.smoothScroll).
// if null (default), $('html, body').firstScrollable() is used.
scrollTarget: null, // only use if you want to override default behavior
beforeScroll: function() {}, // fn(opts) function to be called before scrolling occurs. "this" is the element(s) being scrolled
afterScroll: function() {}, // fn(opts) function to be called after scrolling occurs. "this" is the triggering element
easing: 'swing',
speed: 600,
autoCoefficent: 2 // coefficient for "auto" speed
},
getScrollable = function(opts) {
var scrollable = [],
scrolled = false,
dir = opts.dir && opts.dir == 'left' ? 'scrollLeft' : 'scrollTop';
this.each(function() {
if (this == document || this == window) { return; }
var el = $(this);
if ( el[dir]() > 0 ) {
scrollable.push(this);
} else {
// if scroll(Top|Left) === 0, nudge the element 1px and see if it moves
el[dir](1);
scrolled = el[dir]() > 0;
if ( scrolled ) {
scrollable.push(this);
}
// then put it back, of course
el[dir](0);
}
});
// If no scrollable elements, fall back to <body>,
// if it's in the jQuery collection
// (doing this because Safari sets scrollTop async,
// so can't set it to 1 and immediately get the value.)
if (!scrollable.length) {
this.each(function(index) {
if (this.nodeName === 'BODY') {
scrollable = [this];
}
});
}
// Use the first scrollable element if we're calling firstScrollable()
if ( opts.el === 'first' && scrollable.length > 1 ) {
scrollable = [ scrollable[0] ];
}
return scrollable;
},
isTouch = 'ontouchend' in document;
$.fn.extend({
scrollable: function(dir) {
var scrl = getScrollable.call(this, {dir: dir});
return this.pushStack(scrl);
},
firstScrollable: function(dir) {
var scrl = getScrollable.call(this, {el: 'first', dir: dir});
return this.pushStack(scrl);
},
smoothScroll: function(options) {
options = options || {};
var opts = $.extend({}, $.fn.smoothScroll.defaults, options),
locationPath = $.smoothScroll.filterPath(location.pathname);
this
.unbind('click.smoothscroll')
.bind('click.smoothscroll', function(event) {
var link = this,
$link = $(this),
exclude = opts.exclude,
excludeWithin = opts.excludeWithin,
elCounter = 0, ewlCounter = 0,
include = true,
clickOpts = {},
hostMatch = ((location.hostname === link.hostname) || !link.hostname),
pathMatch = opts.scrollTarget || ( $.smoothScroll.filterPath(link.pathname) || locationPath ) === locationPath,
thisHash = escapeSelector(link.hash);
if ( !opts.scrollTarget && (!hostMatch || !pathMatch || !thisHash) ) {
include = false;
} else {
while (include && elCounter < exclude.length) {
if ($link.is(escapeSelector(exclude[elCounter++]))) {
include = false;
}
}
while ( include && ewlCounter < excludeWithin.length ) {
if ($link.closest(excludeWithin[ewlCounter++]).length) {
include = false;
}
}
}
if ( include ) {
event.preventDefault();
$.extend( clickOpts, opts, {
scrollTarget: opts.scrollTarget || thisHash,
link: link
});
$.smoothScroll( clickOpts );
}
});
return this;
}
});
$.smoothScroll = function(options, px) {
var opts, $scroller, scrollTargetOffset, speed,
scrollerOffset = 0,
offPos = 'offset',
scrollDir = 'scrollTop',
aniProps = {},
aniOpts = {},
scrollprops = [];
if ( typeof options === 'number') {
opts = $.fn.smoothScroll.defaults;
scrollTargetOffset = options;
} else {
opts = $.extend({}, $.fn.smoothScroll.defaults, options || {});
if (opts.scrollElement) {
offPos = 'position';
if (opts.scrollElement.css('position') == 'static') {
opts.scrollElement.css('position', 'relative');
}
}
scrollTargetOffset = px ||
( $(opts.scrollTarget)[offPos]() &&
$(opts.scrollTarget)[offPos]()[opts.direction] ) ||
0;
}
opts = $.extend({link: null}, opts);
scrollDir = opts.direction == 'left' ? 'scrollLeft' : scrollDir;
if ( opts.scrollElement ) {
$scroller = opts.scrollElement;
scrollerOffset = $scroller[scrollDir]();
} else {
$scroller = $('html, body').firstScrollable();
}
aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset;
opts.beforeScroll.call($scroller, opts);
speed = opts.speed;
// automatically calculate the speed of the scroll based on distance / coefficient
if (speed === 'auto') {
// if aniProps[scrollDir] == 0 then we'll use scrollTop() value instead
speed = aniProps[scrollDir] || $scroller.scrollTop();
// divide the speed by the coefficient
speed = speed / opts.autoCoefficent;
}
aniOpts = {
duration: speed,
easing: opts.easing,
complete: function() {
opts.afterScroll.call(opts.link, opts);
}
};
if (opts.step) {
aniOpts.step = opts.step;
}
if ($scroller.length) {
$scroller.stop().animate(aniProps, aniOpts);
} else {
opts.afterScroll.call(opts.link, opts);
}
};
$.smoothScroll.version = version;
$.smoothScroll.filterPath = function(string) {
return string
.replace(/^\//,'')
.replace(/(index|default).[a-zA-Z]{3,4}$/,'')
.replace(/\/$/,'');
};
// default options
$.fn.smoothScroll.defaults = defaults;
function escapeSelector (str) {
return str.replace(/(:|\.)/g,'\\$1');
}
})(jQuery);
your help will be highly appreciated.
I'm guessing this is based on user events so something like this to cover mousescroll and scroll
$(window).bind( "mousewheel DOMMouseScroll scroll", function(e){
if (document.body.scrollTop == 0) {
// do this
}
})

Categories

Resources