Access "this" in Fuel UX placard onAccept function - javascript

I have several Fuel UX placards on a page, with a single jQuery selector to initialize them all. I need to write a custom onAccept function to handle placard confirmation.
It seems like I should be able to access $(this) from within the onAccept to access the element being initialized, but it just points to the window object.
How can I go about accessing the current element in a placard onAccept function?
Here's my code for reference:
$(".select-user-placard").placard({explicit: true, onAccept: function (helpers) {
DMSC.UpdateUser(DMSC.SelectedForm.Id, $(this).data("field-type"), helpers.value);
}});
I need to call this function passing a parameter that is retrieved from a data-attribute on the element, but I'm not sure how I can access the current element without the use of this.

I guess I was kind of thrown by the no access to this and I couldn't think of the obvious solution:
$(".select-user-placard").each(function (index, element) {
var $element = $(element);
$element.placard({explicit: true, onAccept: function (helpers) {
DMSC.UpdateUser(DMSC.SelectedForm.Id, $element.data("field-type"), helpers.value);
}});
});
Instead of calling placard on the jQuery selector, I iterate over each using jQuery's each and just use the jQuery iterator to select that element's data.

Related

jQuery : "this" property is not working on $(document) click

I want to change my clicked image src. I tried it using this. The reason is I am using $(document) for click function. The code I am using is shown below. It will change without using this property. But I need to work it using this property.
$document.on('click', 'img.flagImg', function () {
_flag();
})
var _flag = (function(){
$(this).attr('src',"images/flag.jpg")
})
but its not getting. can any one suggest another option for getting a good solution.
When you call a function like that, _flag(), this is set to the global object (in loose mode) or undefined (in strict mode).
Just let jQuery set this for you:
$document.on('click', 'img.flagImg', _flag);
But if you want to avoid jQuery passing it the event argument, you can use call to set this explicitly instead:
$document.on('click', 'img.flagImg', function() {
_flag.call(this);
});

custom callback on jquery event

I am working with jquery and jstree
I have an event that triggers every time my tree changes:
$tree.jstree()
.on("changed.jstree", function(event, target) {
//manipulate data
});
It works perfect. I can access "this" (the tree), and also event and target. But, I am trying to define a custom callback. I tried something like this:
window.customCallback = (function(event, target) {
//manipulate data
//$(this).foo() manipulates the tree
//event.type to access the event type
//target.node to access the node
}(this));
So I can use:
$tree.jstree()
.on("changed.jstree", customCallback(event, target));
But it doesn't work. Could somebody help me out?
$tree.jstree().on("changed.jstree", customCallback(event, target));
What you're doing is setting the result of customCallback as callback handler.
What you want to do is set the function itself as callback handler:
var customCallback = function(event, target) {
// ...
};
$tree.jstree().on("changed.jstree", customCallback);
Notice the "missing" brackets - because brackets would invoke the function and we don't want that.
The parameters will be passed to the handler automatically.

How to pass `$(this)` as parameter to a "callready" function in Javascript

The leanModal function triggers a modal with some parameters. One of this parameters is a function (ready) that will be executed once the Modal is open. The point is, I need to do some stuff inside that function (ready) just with the element (tag) which triggered the modal, so I need to pass $(this) as parameter to that function. The leanModal() function is provided by MaterializeCss which's the framework that I'm using.
I've been trying this, but thisTag is always undefined. I also have tried to pass directly $(this) to the function, but it also doesn't work at all, it's still undefined. So, how can I reach this?
$('.modal-trigger-editMedic').leanModal({
thisTag: $(this),
ready: function(thisTag){
var refereeNum = thisTag.siblings("[name*='refereeNumToEdit']" )[0].value;
$('#surname').val($("input[id*='medicNameToModal"+refereeNum+"'").val());
}
});
Following the source code, .leanModal supports a ready function (which is triggered once the modal is visible) but doesn't bind or send the element which triggered the modal, the easiest way to fix this is to store a reference outside. To do so, you need to iterate over the triggers yourself instead of relying on that functionality of provided by this jQuery plugin.
Like so:
var $surname = $('#surname'); // you should store the selector as a reference
// outside the loop for better performance
$('.modal-trigger-editMedic').each(function() {
var $this = $(this); // this is the current item in the set of elements,
// therefore our trigger element
// EDIT: using var makes this a local variable
$this.leanModal({
ready: function() {
var refereeNum = $this.siblings("[name*='refereeNumToEdit']" )[0].value;
$surname.val($("input[id*='medicNameToModal"+refereeNum+"'").val());
}
});
});
When you are inside the leanModal it becomes this. Try setting a var to $(this) and pass that through.
var that = $(this);
$('.modal-trigger-editMedic').leanModal({
thisTag: that,
ready: function(thisTag){
var refereeNum = thisTag.siblings("[name*='refereeNumToEdit']" )[0].value;
$('#surname').val($("input[id*='medicNameToModal"+refereeNum+"'").val());
}
});

Is there a way to watch attribute changes triggered from outside the AngularJS world?

Iā€™m trying to understand interactions between the Angular world and the non-Angular world.
Given a directive that one declares like this:
<dir1 id="d1" attr1="100"/>
If code outside angular changes the directive this way:
$("#d1").attr("attr1", 1000);
How can the directive know that one of its attribute has changed?
It would be best to make this change inside the directive instead. If, for whatever reason, that's not possible, then there are a couple of options.
Outside the app, get a reference to any DOM element within the app. Using that reference, you can then get a reference to its scope. You could use your element with id d1. For example:
var domElement = document.getElementById('d1');
var scope = angular.element(domElement).scope();
Here are a couple of options:
Option 1
Modify the model instead of making a direct change to the view. In the link function, store the initial attribute value in a scope variable like:
scope.myvalue = attrs.attr1;
Then you can change the value outside the app (using the above reference to scope) like:
scope.$apply(function(){
scope.myvalue = 1000;
console.log('attribute changed');
});
Here is a fiddle
Option 2
If the view is manipulated directly with jQuery, I don't know of any use of $observe, $watch, or an isolate scope binding to the attribute that will work, because they all bind to the attribute expression itself, just once, when the link function is first run. Changing the value will cause those bindings to fail. So you'd have to $watch the attribute on the DOM element itself (rather than through attrs):
scope.$watch(function(){
return $(el).attr('attr1'); // Set a watch on the actual DOM value
}, function(newVal){
scope.message = newVal;
});
Then you can change the value outside the app (using the above reference to scope) like:
scope.$apply(function(){
$("#d1").attr("attr1",1000);
});
Here is a fiddle
Use a Web Components library like x-tags by Mozilla or Polymer by Google. This option works without maunally calling $scope.$apply every time the attribute changes.
I use x-tags because of their wider browser support. While defining a new custom tag (directive) you can set the option lifecycle.attributeChanged to a callback function, which will fire every time an argument is changed.
The official docs aren't very helpful. But by trial and error and diving into the code I managed to find out how it works.
The callback function's context (the this object) is the element itself. The one whose attribute has changed. The callback can take three arguments:
name ā€“ the name of the attribute,
oldValue and
newValue ā€“ these speak for themselves.
So now, down to business:
The code
This will watch the attribute for changes:
xtag.register('dir1', {
lifecycle: {
attributeChanged: function (attribute, changedFrom, changedTo) {
// Find the element's scope
var scope = angular.element(this).scope();
// Update the scope if our attribute has changed
scope.$apply(function () {
if (attribute == 'attr1') scope.style = changedTo;
});
}
}
});
The attributeChanged callback only fires when the arguments' values actually change. To get their initial values you need to scan the lot manually. The easiest way seems to be while defining the directive:
myApp.directive('dir1', function () {
return {
... ,
link: function (scope, element, attributes) {
scope.attr1 = element[0].getAttribute('attr1');
}
};
});

How can I create functions in jQuery and call it on event and pass variable to it?

$(".addcart").click(function(){
$("input[name='items']:checked").each(function() {
//doing something
});
});
I'm trying to create a common class onclick of which I'm doing something. Is there a way I can make "items" a variable, I mean Can I pass checkbox name to this event.
Try this and see if it works out:
$("input[name='items']:checked").each(function() {
alert(this.attr("name"));
});
I think I've used like this somewhere.
[EDIT]
The thing with this is that jQuery passes the current item to the foreach as the context of the variable.
Use bind instead of click
$(".addcart").bind("click", {name: "items"}, function(event){
$("input[name='" + event.data.name + "']:checked").each(function() {
//doing something
});
});
edit:
"How can I create functions in jQuery
and call it on event and pass variable
to it"
That will still be the same procedure. Use bind to attach an event handler, pass it an object with the needed stuff for your function. In your event handler call your function and pass it the object from event.data
$(".addcart").bind("click", {foo: "hello world"}, function(event) {
DoSomethingOnClick(event.data);
});
function DoSomethingOnClick(obj) {
obj = obj || {};
if (obj.hasOwnProperty('foo'))
alert(obj["foo"]);
else
alert("no foo here");
}
You know that all checked items will have a name of items, so that's not very interesting, but maybe you want to retrieve the value of each of the items:
$(".addcart").click(function(){
$("input[name='items']:checked").each(function() {
// To access an attribute of this item use the form $(this).attr(...)
alert( this.value );
});
});
The above uses this to access the element being iterated over. Take a look at the properties of a DOM element to see what properties of this you can access.
You can create a jQuery object out of this using the form $(this) then you can use .attr() to access the attributes of this. For example to get the class/es of this you can use either this.className or $(this).attr("class").
It is faster to directly access the DOM element's properties. But for some more complex manipulations it is good to know that $(this) is also available.

Categories

Resources