I am using the combination of a data attribute and class name to fire a function to modify the content of the element with the particular class name.
Below function fires at $(document).ready
$('.accessControlled').each(function(){
var accessLevel = parseInt($(this).attr("data-accesslevel"));
if((user.role !== 0) && (accessLevel !== role)){
$(this).remove();
} else {
$(this).removeAttr('data-accesslevel');
$(this).removeClass('accessControlled');
}
});
Now I want to fire this function, on elements returned by ajax calls too.
I know I can bind the functions permanently by jquery on(), live(), delegate(), etc, but which event to use and how to go about it?
Just execute the code above against returned code:
eg:
function doit(obj){
$(obj).each( // rest of your function
}
// ...
$.get(...).done(function(data){
var obj = $(data);
doit(obj);
// rest of your injection
}
Try this:
// obviously user.role and role must be defined for this to work
function access(){
$('.accessControlled').each(function(){
var accessLevel = parseInt($(this).attr("data-accesslevel"));
if((user.role !== 0) && (accessLevel !== role)){
$(this).remove();
}
else{
$(this).removeAttr('data-accesslevel');
$(this).removeClass('accessControlled');
}
});
}
// assign each ajax call to a variable
var ajx1 = $.post({/*object stuff here*/});
// put the ajax variables in an Array
var ajxA = [ajx1, ajx2, ajx3, ajx4, ajx5, ajx6, ajx7];
$.each(ajxA, function(i, v){
v.done(access);
});
There is a function ajaxSuccess in jQuery which can be used to do something after all ajax calls.
$(document).ajaxSuccess(function() {
accessControl.checkAccessControl();
});
Related
I have a few links. When I hover mouse over the links I would like to get the values stored in data attributes. I need to pick the t values and pass them into function
HTML
<a href="#" data-lat="23.333452" data-lon="-97.2234234">
JS
var loc = document.querySelectorAll("a[data-lat]");
loc.addEventListener("mouseover", locOver);
loc.addEventListener("mouseout", locOut);
function locOver() {
// do something
}
function locOut() {
// do something else
}
It's been a while since I used vanilla JS and it's been a long day so I'm sure it's pretty close but I'm stuck. I keep getting:
Uncaught TypeError: loc.addEventListener is not a function
What am I missing here?
You need to loop through the nodes that you obtained with document.querySelectorAll("a[data-lat]") for adding events.
Working example.
Node
<script>
var loc = document.querySelectorAll("a[data-lat]");
loc.forEach(node => {
node.addEventListener("mouseover", locOver);
node.addEventListener("mouseout", locOut);
})
function locOver(event) {
// do something
console.log('mouseover', event.target.dataset)
}
function locOut() {
// do something
console.log('locOut')
}
</script>
const loc = document.querySelector("a[data-lat]");
const locOver = () => {
console.log("Mouse is over the link");
}
const locOut = () => {
console.log("Mouse is out of the link");
}
loc.addEventListener("mouseover", locOver);
loc.addEventListener("mouseout", locOut);
Link
Explanation:
I target the link using .querySelector method that returns a single node.
After that i created two event handler for mouseOver and mouseOut and than i added the eventListener to the link.
I got this to work as expected by hard-coding the class prefix directly into the match():
(function($){
jQuery.fn.extend({
removePrefixClass:function(classPrefix){
$(this).removeClass(function(index, css){
return(css.match(/(^|\s)notice-\S+/g) || []).join(' ');
});
}
});
})(jQuery);
How can I put the function parameter classPrefix inside the match()?
The usage in this case would be $(this).removePrefixClass('notice-') in order to remove any class that is named notice-success, notice-error, notice-warning so on and so forth...
I've seen some answers here where the use of RegExp is suggested. But can't seem to figure it out how to use it in my scenario.
Here is the part of the code where it's in use:
(/* ajax request* / > .done > if there's an existing #notice)
$(function(){
$("form.ajax").submit(function(e){
e.preventDefault();
if($('form[id]').length){ // make sure the form has a unique id
let $form = $('form#'+$(this).attr('id')); // use this specific form
let $formNotice = $form.find('#notice'); // locate #notice element
/* ajax request */
submitAjax($form) // personal wrapper function that just returns an $.ajax({...})-object
.done(function(data,statusText,jqXHR){
if($formNotice.length){ // update existing notice
/*--> */ $formNotice.removePrefixClass('notice-'); // remove class that starts with "notice-"
$formNotice.prependClass('notice-'+data['type']); // add new `notice-`class to the beginning to make it work
$formNotice.find('p').html(data['msg']); // add response message
} else { // set new #notice
$(setNotice(data['type'],data['msg'])).hide().prependTo($form).slideDown("slow"); // personal function that returns the `notice-`-html-element
}
})
.fail(function(){
console.log('fail : '+statusText);
})
.always(function(){
console.log('always');
});
//
} else {
console.log('form is missing id');
}
});
});
You need to build a RegExp object explicitly, like this:
removePrefixClass: function(classPrefix) {
var re = new RegExp('(^|\s)' + classPrefix + '\S+', 'g');
$(this).removeClass(function(index, css) {
return(css.match(re) || []).join(' ');
});
}
I´m building a jQuery extension plugin with the following standard:
(function ($) {
var version = "1.1.0";
var active = false;
$.fn.inputPicker = function (options) {
return this.each(function () {
if ($(this)[0].tagName !== 'DIV')
throw new ReferenceError('mz.ui.dialog.dateTimePicker: Method works only on DIV types.');
/// Label
var labelObj = $("<label class='small'>Data Hora Inicial</label>");
$(this).append(labelObj);
/// Input
var inputObj = $("<input type='datetime-local' class='form-control input-sm'></input>");
$(this).append(inputObj);
})
});
};
}(jQuery));
And here is how I call it:
<div id='test'></div>
$('#test').inputPicker();
Later in code I wanna get the data that was entered in the input field, something like:
$('test').inputPicker().getInputData();
What´s the best way to accomplish that ? I´ve tried something like:
this.getInputData = function () {
return $(inputObj).val();
}
But got errors when calling the function.
Can someone help me with this ? Thanks in advance...
You could just make another method to get the input data like this using the DOM structure and class names that you added:
$.fn.getInputData = function() {
return this.eq(0).find("input.input-sm").val();
}
This would operate only on the first DOM element in the jQuery object (since it's returning only a single value).
So, after setting it up like you did:
$("#test").inputPicker();
You'd then retrieve the data like this:
var data = $("#test").getInputData();
HTML part:
foo
JS part:
function callme() {
var me = ?; //someway to get the dom element of the a-tag
$(me).toggle();
}
in the JS part can i somehow get the a-tag that this function was called from?
i know i could just pass it as a parameter, but this function is used many many times on a page and i want to avoid putting the parameter everywhere.
thanks!
Since you are using an onclick attribute (BAD!) you have to pass that into the function.
onclick="callme(this); return false;"
and the js:
function callme(el) {
var $me = $(el);
$me.doSomething();
}
Another option is to set the context of the function using .call().
onclick="callme.call(this,event)"
and the js
function callme(event) {
event.preventDefault();
$(this).doSomething();
}
I have a simple JS function for that
function getEventTarget(event) {
var targetElement = null;
try {
if (typeof event.target != "undefined") {
targetElement = event.target;
}
else {
targetElement = event.srcElement;
}
// just make sure this works as inteneded
if (targetElement != null && targetElement.nodeType && targetElement.parentNode) {
while (targetElement.nodeType == 3 && targetElement.parentNode != null) {
targetElement = targetElement.parentNode;
}
}
} catch (ex) { alert("getEventTarget failed: " + ex); }
return targetElement;
};
in your html
foo
in your function
function callme(event) {
var me = getEventTarget(event); //someway to get the dom element of the a-tag
$('#'+ me.id).toggle();
}
getEventTarget() will bring back the whole dom object which you can manipulate as you please, or has been said already by other users you can just use
function callme(event) {
$(this).toggle();
}
send this parameter to your function.
foo
function callme(me) {
$(me).toggle();
}
better dont use onlcick in html markup
$(document).ready(function() {
$("a").click(callme);
})
function callme() {
var me = this;
$(me).toggle();
}
All,
I am really stuck/ confused at this point.
I have an array with 6 items in it. Each item in the array is dynamically filled with elements using jquery '.html' method. However, I cannot seem to be able to attach/ bind an event to this dynamically created variable.
As soon as the browser gets to the problem line (see the area labeled 'PROBLEM AREA'), I get a 'undefined' error, which is really confusing as all the previous code on the very same variable works just fine.
var eCreditSystem = document.getElementById("creditSystem");
var i = 0;
var eCreditT = new Array(6); // 6 members created which will be recycled
function createCreditTransaction () // func called when a transaction occurs, at the mo, attached to onclick()
{
if (i < 6)
{
eCreditT[i] = undefined; // to delete the existing data in the index of array
addElements (i);
} else
if (i > 5 || eCreditT[i] != undefined)
{
...
}
}
function addElements (arrayIndex) // func called from within the 'createCreditTransaction()' func
{
eCreditT[i] = $(document.createElement('div')).addClass("cCreditTransaction").appendTo(eCreditSystem);
$(eCreditT[i]).attr ('id', ('trans' + i));
$(eCreditT[i]).html ('<div class="cCreditContainer"><span class="cCreditsNo">-50</span> <img class="cCurrency" src="" alt="" /></div><span class="cCloseMsg">Click box to close.</span><div class="dots"></div><div class="dots"></div><div class="dots"></div>');
creditTransactionSlideOut (eCreditT[i], 666); // calling slideOut animation
console.log(eCreditT[i]); // this confirms that the variable is not undefined
/* ***** THE PROBLEM AREA ***** */
$(eCreditT[i]).on ('click', function () // if user clicks on the transaction box
{
creditTransactionSlideBackIn (eCreditT[i], 150); // slide back in animation
});
return i++;
}
Try this:
$(eCreditT[i]).bind('click', function() {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
Edit: use ++i instead of i++ like this:
return ++i;
/*
or
i += 1;
return i;
*/
retrurn ++i performs the increment first then return i after the increment.
While return i++ return i then icrement it.
Try to add click event out of addElements() function and try once.
Nonsense create an element using JavaScript and then use jQuery function to transform it into a jQuery object. You can let jQuery create the element directly for you.
eCreditT[i] = $('<div>').addClass("cCreditTransaction").appendTo(eCreditSystem);
Also, since eCretitT[i] is already a jQuery element, no need to call the jQuery function again.
eCreditT[i].on('click', function () {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
If you already tried on, bind, live and click methods, then maybe the called function is your problem. Try to put a console.log() or an alert() inside the function to make sure the click event is actually happening. If it happens then the function creditTransactionSlideBackIn() is your problem.
EDIT
The problem is when the event takes place, i is not the original variable anymore.
function addElements (arrayIndex)
{
eCreditT[i] = $('<div>').addClass("cCreditTransaction").appendTo(eCreditSystem);
eCreditT[i].attr ('id', ('trans' + i));
eCreditT[i].data ('id', i); // Store the id value to a data attribute
Then when you call the function you can refer to the data attribute instead of the i variable:
/* ***** THE PROBLEM AREA ***** */
eCreditT[i].on ('click', function () // if user clicks on the transaction box
{
creditTransactionSlideBackIn ($(this).data('id'), 150); // slide back in animation
});
return i++;
}
try to bind parent div and then use if($e.target).is('some')){}, it will act as .live, like this:
$(eCreditSystem).bind('click', function (e){
if($(e.target).is('.cCreditTransaction')) {
creditTransactionSlideBackIn ($(e.target), 150);
}
});
of course you'll need in a minute larger if for checking if clicked dom el is a child of .cCreditTransaction, like this:
if($(e.target).parents().is('.cCreditTransaction')){}
Try this:
$(eCreditT[i]).live('click', function() {
creditTransactionSlideBackIn(eCreditT[i], 150);
});