Can I add a variable or a function in a mdDialog? - javascript

I want to add a variable or a function to my mdDialog. Im not to sure on how to create a custom mdDialog, Im new to angularjs.
This is my mdDialog:
vm.dialog_up = function() {
vm.dis = true;
alert = $mdDialog.alert()
.title('Attention, ')
.content('Do you want to edit your Information?')
.ok('Close');
$mdDialog
.show( alert )
.finally(function() {
alert = undefined;
});
}
I want to maybe add a function to the .ok button.

JavaScript is a very liberal language and it allows you to add properties and methods to objects. For example:
var modal = {};
modal.x = 5;//this assigns the value of `5` to the newly attached property `x`
modal.testMethod = function() {
//Do something here
}
PS:
Though personally, I think that modifying framework objects can cause side effects.

Related

Call method inside function

i have a wizard from a metronic theme where I'm trying to call a function to check if my array contains dublicates.
if I remove this part of my code it works without problems.
console.log(this.checkIfArrayIsUnique());
code
var wizard = (<any>$('#m_wizard')).mWizard();
//== Validation before going to next page
wizard.on('change', function(wizard) {
if(wizard.getStep() > 2){
console.log(this.checkIfArrayIsUnique());
}
mApp.scrollTop();
})
Right now my checkIfArrayIsUnique() is just a dummy function
checkIfArrayIsUnique()
{
return true;
}
how can i call a method outside my 'change' event ? So I'm able to run thru my array and confirm it does not have any dublicates.
the problem is the "function(wizard)" call, since it creates a new scope. But your checkIfArrayIsUnique() ist actually outside of this scope.
Try using ES6 function syntax
wizard.on('change',(wizard) => {
if(wizard.getStep() > 2){
console.log(this.checkIfArrayIsUnique());
}
mApp.scrollTop();
})
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
in your change function the variable this point to current function,to use it,you should make this point to out object,you should write like this:
var that = this;
var wizard = (<any>$('#m_wizard')).mWizard();
//== Validation before going to next page
wizard.on('change', function(wizard) {
if(wizard.getStep() > 2){
console.log(that.checkIfArrayIsUnique());
}
mApp.scrollTop();
})

How do you use Javascript constructor methods in a jQuery statement?

I can't figure out how to use a Javascript constructor method in a jQuery .click method. I'm trying to get a button's function to change dynamically based on a constructor. Here's the set up:
<button onclick="">
</button>
needs to call a method that changes depending on another button. The following is my broken code:
function GloveMode (name , array) {
this.colorArray = array;
this.displaySettings = function(){
//Title
$("#displayTitle").text(this.name);
//Display Color Set
$("#displayColors").empty();
//Totally Broken
$("#upArrow").click( function(){
addColor();
});
};
this.addColor = function(){
console.log(this.colorArray.length);
};
};
I can't figure out how to get $("#upArrow").click() to call this.colorArray properly, or how to call this.addColor() in the .click() method! Please help.
Your Problem is that "this" means something different in each function body. So save the wanted "this" to a variable e.g. "self" and use that.
function GloveMode (name , array)
{
var self = this;
this.colorArray = array;
this.displaySettings = function()
{
//Title
$("#displayTitle").text(this.name);
//Display Color Set
$("#displayColors").empty();
//Totally Broken
$("#upArrow").click( function()
{
self.addColor();
});
};
this.addColor = function()
{
console.log(self.colorArray.length);
};
};

changing prototype Elements set scopes

I am wanting to attach into an Elements default property such as innerHTML as a backup under an object that way it does not pollute the Elements properties. so to help give an idea of what I am trying to achieve and what currently works:
Element.prototype._backupPropertyDescriptors = {};
Element.prototype._backupProperties = {};
Element.prototype._backupPropertyDescriptors._innerHTML = Object.getOwnPropertyDescriptor(Element.prototype,'innerHTML');
//This is what I want to do but loses Elements scope:
Object.defineProperty(Element.prototype._backupProperties,'_innerHTML',Element.prototype._backupPropertyDescriptors._innerHTML);
//the scope has changed from element to _backupProperties so this property fails.
//The working version:
Object.defineProperty(Element.prototype,'_innerHTML',Element.prototype._backupPropertyDescriptors._innerHTML);
//the reason for this is I want to be able to manipulate the get and set such as:
Object.defineProperty(Element.prototype._backupProperties,'_innerHTML',{configurable:true,enumerable:true,get:function(){console.log('getting',this.innerHTML);return this.innerHTML},set:function(val){console.log('doing something here before setting');this.innerHTML = val;}});
The problem with this is once it is inside of backup the this statement no longer holds the element...
I know one way to do this would be to use a bind or call but that still poses the how do I get the elements scope... as this during define property is the window..
So for anyone looking to try and do this, here is the solution I found :) might be something better out there, but this does work. requires only 3 properties in the prototype and then all others get put inside a single one.
Element.prototype._backupPropertyDescriptors = {};
Element.prototype._backupProperties = {};
Object.defineProperty(Element.prototype,'_backupProvider',
{
writeable:false,
enumerable:true,
configurable:true,
get:function()
{
var _backupProperties = this._backupProperties;
_backupProperties._Element = this;
return {_Element:this,_backupPropertyDescriptors:this._backupPropertyDescriptors,_backupProperties:_backupProperties};
}
});
//These first ones set up the main provider and property and descriptor holders.
//then just copy a descriptor:
Element.prototype._backupPropertyDescriptors._innerHTML = Object.getOwnPropertyDescriptor(Element.prototype,'innerHTML');
//and assign it to a new property inside the backupProperties:
Object.defineProperty(Element.prototype._backupProvider._backupProperties,'_innerHTML',
{
enumerable:true,
configurable:true,
get:function()
{
return this._Element._backupProvider._backupPropertyDescriptors._innerHTML.get.call(this._Element);
},
set:function(val)
{
console.log('setting html to: ',val);
this._Element._backupProvider._backupPropertyDescriptors._innerHTML.set.call(this._Element,val);
}
});
//and if you wanted to do something really crazy.... like overwrite the original..
Object.defineProperty(Element.prototype,'innerHTML',
{
enumerable:true,
configurable:true,
get:function()
{
return this._backupProvider._backupProperties._innerHTML;
},
set:function(val)
{
console.log('setting html to: ',val);
//do some crazy two way template binding here or something else crazy
this._backupProvider._backupProperties._innerHTML = val;
}
});
that is all.. thanks for the help #Bergi

In a custom widget, inside a validation handler of addMethod(), I have a wrong context (this)

I'm creating a custom combobox which uses jQuery validator.
At first they all are gray except the first (it means Country). When I choose 'Slovenská republika' the second combobox is enabled.
They all are instances of a a custom autocomplete combobox widget.
To enable the validation I use this code (which is called within _create: function(){..})
There you can find $.validator.addClassRules(); and $.validator.addMethod(). I also added the appropriate class so it really does something.
_registerCustomValidator: function(){
var uniqueName = this._getUniqueInstanceNameFromThisID(this.id);
var that = this;
console.log(this.id);//this prints 5 unique ids when the page is being loaded
$.validator.addMethod(uniqueName, function(value,element){
if(!that.options.allowOtherValue){
return that.valid;
}
console.log(that.id);//this always prints the ID of the last combobox StreetName
return true;
}, "Error message.");
var o = JSON.parse('{"'+uniqueName+'":"true"}');
$.validator.addClassRules("select-validator", o);
}
//this.id is my own property that I set in _create
Problem: When I change the value of any instance of combobox, it always prints the ID of the last instance StreetName, but it should belong to the one that has been changed.
I thought it might be because of registering $.validator.addMethod("someName",handler) using such a fixed string, so now I pass a uniqueName, but the problem remains.
Therefore the validation of all instances is based on the property allowOtherValue of the last instance.
I don't understand why it behaves so. Does anyone see what might be the problem?
EDIT:
see my comments in the following code
_registerCustomValidator is a custom function within a widget factory.
//somewhere a global var
var InstanceRegistry = [undefined];
//inside a widget factory
_registerCustomValidator: function(){
var i=0;
while(InstanceRegistry[i] !== undefined) ++i;
InstanceRegistry[i] = this.id;
InstanceRegistry[i+1] = undefined;
var ID = i; //here ID,i,InstanceRegistry are correct
$.validator.addMethod(uniqueName, function(value,element){
//here InstanceRegistry contains different values at different positions, so its correct
console.log("ID=="+ID);//ID is always 5 like keeping only the last assiged value.
var that = InstanceRegistry[ID];
if(!that.options.allowOtherValue){
return that.valid;
}
return true;
}, "Error message");
var o = JSON.parse('{"'+uniqueName+'":"true"}');
$.validator.addClassRules("select-validator", o);
}
It looks like a sneaky combination of closure logic and reference logic. The callback in $.validator.addMethod is enclosing a reference to this which will equal the last value of this when $.validator.addMethod. (Or something like that?)
Glancing at your code, it's not clear to me what this is in this context. So I can't really offer a concrete solution. But one solution might be to create some kind of global registry for your thises. Then you could do something along the lines of:
_registerCustomValidator: function(){
var uniqueName = this._getUniqueInstanceNameFromThisID(this.id);
$.validator.addMethod(uniqueName, function(value,element) {
var instance = InstanceRegistry[uniqueName];
if(! instance.options.allowOtherValue){
return instance.valid;
}
return true;
}, "Error message.");
var o = JSON.parse('{"'+uniqueName+'":"true"}');
$.validator.addClassRules("select-validator", o);
}
The registry could be keyed to uniqueName or id, just so long as it is a value getting enclosed in your callback.

Changing the state of a toggle in JavaScript/jQuery

Is it possible to change the state of a toggle function? Like:
myDiv.toggle ... function 1 , function 2
I click on the myDiv element, the function 1 executes
I click again, function 2
I click again, function 1
BUT
Change the state
function 1 again
etc.
But I need to be able to change the state from outside the toggle function.
Here is a javascript object that uses closure to track it's state and toggle:
var TOGGLER = function() {
var _state = true;
var _msg = "function1";
var function1 = function() {
_msg = "function1";
}
var function2 = function() {
_msg = "function2";
}
return {
toggle: (function () {
_state = !_state;
if (_state) {
function1();
} else {
function2();
}
return _msg;
})
}
}();
Here is a jsfiddle that shows how to use it to toggle based with the following jquery: http://jsfiddle.net/yjPKH/5/
$(document).ready(function() {
$("#search").click(function() {
var message = TOGGLER.toggle();
$("#state").text(message);
});
});
The toggle function is meant for simple use cases. Changing the state externally is not "simple" anymore.
You cannot easily/safely (it's internal so it may change during minor versions) access the state variable of the toggle function easily as it's stored in the internal dataset of the element.
If you really want to do it, you can try this code though:
$._data(ELEMENT, "lastToggle" + func.guid, 0);
func is the function you passed to .toggle(), so you need to save this function in a variable. Here's a minimal example: http://jsfiddle.net/xqgrP/
However, since inside the function there's a var guid = fn.guid || jQuery.guid++ statement, I somehow think that the devs actually meant to use guid instead of func.guid for the _data key - in that case a minor update is very likely to break things. And after the fix you'd have to iterate over the data set to retrieve the correct key as there is no way to access the guid from outside.

Categories