Reputation: 329
I have an object which is called by two different variables. Is there any way to find out - inside the object function - which variable is calling it?
sp = new SelectedPlaylists("tableSelectedPlaylists");
sa = new SelectedPlaylists("tableSelectedAlbums");
These are the two variables
Upvotes: 1
Views: 71
Reputation:
I believe your question is phrased a bit inaccurately. What I think you intended is that when a button is clicked to remove, then the removeRowWithTd is executed on the object which created the row in the first place.
To do this, one method is to attach the event handler after adding the element into the DOM and then passing a function which references the instance which created the element. I have made some adjustments as you did not provdie the full code, but the following works for me in a browser, accurately adding rows to the respective tables and removing them. Please note that the comments in the code matter. I had to make changes to get this to work on my end.
<!DOCTYPE HTML>
<html>
<head>
<title>Testing Script</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<style type="text/css">
.playlist_button {
background: none !important;
border: none;
padding: 0 !important;
border-bottom: 1px solid #444;
cursor: pointer;
}
</style>
</head>
<body>
<table id="tableSelectedPlaylists">
<tbody></tbody>
</table>
<table id="tableSelectedAlbums">
<tbody></tbody>
</table>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
// A placeholder definition
SelectedPlaylists = function(tableId) {
//Assumed functionality
this.reftable = $('#' + tableId);
this.arrPlaylists = [];
this.removeRowWithTd = function(source) {
source.parent().parent().remove();
}
};
//Extension to the prototype
SelectedPlaylists.prototype.addPlaylist = function(id, name) {
if (!id)
return -1;
var that = this;
var tablebody = this.reftable.children('tbody');
var found = false;
/* Removed ONLY for my testing as it served no purpose
var rownode = this.getRowNodebyPlaylistID(id)
if (rownode) {
return -1;
}
*/
this.arrPlaylists.push({
id : id,
name : name
});
demo = typeof this;
tablebody.append('<tr><td class="name">' + name
+ '</td><td class="id">' + id
// Next line adds id for reference after being added to DOM
+ '</td><td><button id="' + this.reftable.id + '_button_' + id
// Yes, I moved your CSS into the stylesheet and replaced with a class
+ '" class="playlist_button">Remove</button></td></tr>');
//Now, attach an onClick handler as the return of a function which gets passed itself
//and then returns another function which executes the desired method.
$('#' + this.reftable.id + '_button_' + id).on('click', function(instanceObj) {
return function() {
instanceObj.removeRowWithTd($(this));
}
}(this));
}
//Instantiation
sp = new SelectedPlaylists("tableSelectedPlaylists");
sa = new SelectedPlaylists("tableSelectedAlbums");
//Calling the new method
sa.addPlaylist(1, 'ABC');
sp.addPlaylist(2, 'DEF');
</script>
</body>
</html>
Finally, the assertion that if
is a bad programming practice is absurd. Use of them where other alternatives exist can make a script more efficient (and in cases such as loop-invariance). While I have almost no knowledge of assembly, it appears that that construct is in assembly, too. Use your tools wisely, but don't empty your toolbox for the sake of lack of skill. Now, if you want a challenge to whoever made up this rule, tell them to write their scripts without conditionals and only using the Heavyside step function.
Happy coding!
Upvotes: 0
Reputation: 1638
I think you could create a variable inside SelectedPlaylists
class to determine which type of playlists and pass it trhough constructor:
sp = new SelectedPlaylists("tableSelectedPlaylists", "p");
sa = new SelectedPlaylists("tableSelectedAlbums", "a");
In the consctructor:
function SelectedPlaylists(id, type)
{
// ... Your code ...
var manageType=type;
var buttonLabel='';
switch(type)
{
case 'p':
// Playlist mode
this.buttonLabel='Remove Playlist';
case 'a':
// Album mode
this.buttonLabel='Remove Album';
}
}
Store the second param in a variable (for example manageType
) and use when needed (take a look to a textOnClick
var):
SelectedPlaylists.prototype.addPlaylist = function (id, name)
{
if( !id ) return -1;
var that = this;
var tablebody = this.reftable.children('tbody');
var found = false;
var rownode = this.getRowNodebyPlaylistID(id);
if(rownode)
{
return -1;
}
this.arrPlaylists.push({id:id,name:name});
demo = typeof this;
tablebody.append("<tr><td class='name'>"+name+"</td><td class='id'>"+id+"</td><td><button style='background:none!important;border:none;padding:0!important;border-bottom:1px solid #444; cursor: pointer' onclick='sp.removeRowWithTd( $(this)); console.log($(this))'>"+this.buttonLabel+"</button></td></tr>");
Thus, the code is better to reuse and control and all the configuration is done in constructor.
Hope it helps!
Upvotes: 2
Reputation: 114481
No you cannot. Note that may be there's not even a variable used to store the object... code like L.push(new Foo(1))
is perfectly valid and no named variable is going to be used to store the created object).
What is normally done in these cases is to provide other parameters to the object constructor so you can use this extra parameter in the processing to decide what to do.
Also it's better if you move the actual processing out of the constructor in a closure so increasing the possibility that the same code can be reused again in other cases... for example:
function addButton(text, classname, container, f) {
var b = document.createElement("input");
b.type = "button";
b.value = text;
b.className = classname;
container.appendChild(b);
b.onclick = f;
return b;
}
addButton("b1", "redbutton", menu, function() { alert("You pressed b1"); });
addButton("b2", "bluebutton", menu2, function() { alert("You pressed b2"); });
passing the closure f
you're leaving absolute freedom on what the button could be used to do when pressed
Upvotes: 0