'alert' an object property on click - javascript

I have a constructor which I then make the object library_science1 with:
function librarytech(humanity,food,wood,metal,wealth)
{
this.humanity=humanity;
this.food=food;
this.wood=wood;
this.metal=metal;
this.wealth=wealth;
}
var library_science1=new librarytech(0,200,200,0,0);
I have this as a click function:
$("[id^='library_']").click(function() {
var idd = this.id;
alert(idd);
});
where the html is simply
<span id='library_science1'></span>
The code above works fine, alerting 'library_science1' nicely... it even works when I use the alert to directly pull one of the objects properties.
$("[id^='library_']").click(function() {
alert(library_science1.food);
});
But I have many library_[SOMETHING] objects, corresponding each to there own
<span id="library_[SOMETHING]"></span> line.
I'm trying to pull the objects properties depending on which one is clicked. Such as:
$("[id^='library_']").click(function() {
alert(this.id.food);
});
or
$("[id^='library_']").click(function() {
var x = this.id;
alert(x.food);
});
The end purpose being that I can ultimately do things like:
foodamount -= this.id.food
Why isn't this working :/ :(

simply because you are accessing an object in your first example and not a DOM object as in other, if their obejtos are global so you can access
alert(window[this.id].food);
or
alert(eval(this.id + ".food"));

I made a test here using eval() and this works:
$("[id^='library_']").click(function() {
alert(eval(this.id).food);
});
$("[id^='library_']").click(function() {
var x = eval(this.id);
alert(x.food);
});

Related

Storing Jquery reference

Is it possible to store the reference to an element in an array or object without having a unique ID on the element?
I am having trouble with storing a subtable in another table so I can reference it later. I get the table by class with this code:
$(this).parent('tr').parent().find('.tableSomeTable');
Is the only solution to have unique id's on each element and use the .selector method?
More of my code. Abit simplified.
var rows = [];
var historyLoad;
$(document).on("click", '.details-control', function (e) {
var t = $(this);
var tr = t.closest('tr');
var row = t.parent().parent().parent().DataTable().row(tr);
var id = t.closest('tr').attr('id');
var object = {
id: id,
btnHistory: t.parent('tr').next().find('#btnHistory'),
tblHistory: t.parent('tr').parent().find('.tableHistory'),
historyLoad: historyLoad
};
if ($.inArray(id, rows) > -1) {
loadData = false;
}
else {
loadData = true;
loadHistory(object);
rows.push(object);
}
};
Here is where I am having trouble retrieving the correct elements. And I also want to save the ajaxHistory element to my object (which is working fine).
This code is not working, but if I change it to $(result.btnHistory.btnHistory.selector) I get the object. But this doesn't seem to work very good with multiple rows.
function loadHistory(result) {
result.ajaxHistory = $.ajax({
...
beforeSend: function () {
$(result.btnHistory).html(<loading txt>);
$(result.tblHistory).find('tbody').html(<loading txt>);
},
....
success: function (data) {
if (data.TotalRecordCount > 0) {
$(result.tblHistory).find('tbody').html('');
$.each(data.Records, function (e, o) {
$(result.tblHistory).find('tbody').append(<data>)
});
}
else {
$(result.tblHistory).find('tbody').html(<txt no records>);
}
$(result.btnHistory).html(<txt loading done>));
},
First off, if you are trying to find the parent table, try
var $myObj = $(this).closest('table.tableSomeTable');
instead of navigating parents.
As far as storing the jQuery reference, define a variable and then store it. The above will store the object in $myObj but that is locally scoped. If you need a global variable then define it globally and just assign it here. If you want to define it as a property within an object then define it that way. It really comes down to a scope question at this point.
EDIT: Just saw your added content.
First off, don't name it 'object'. This may run into key word issues. Use var myObj or similar instead. Next, object.btnHistory is a reference to a jQuery object. So, when you pass it to loadHistory, you do not need to apply the $(...) again. Just use the reference directly: result.btnHistory.html(...). A good habit to get into is prepending you jQuery variables with $ so you remember it is already a jQuery variable.
The .find() method returns a jQuery object. So the answer is, yes, you can store this return object in a variable:
var $yourObject = $(this).parent('tr').parent().find('.tableSomeTable');

efficiently creating variables when a checkbox is checked and using these variables later in the code

below is the information I need help with.
$(document).ready(function(){
$('.checkboxes :checkbox').click(function(){
if($(this).is(':checked')){
console.log(this.id + this.checked)
i want to set a variable with the samename of the id of the checked box
so if showItems was checked i would have a variable
var showItems = true;
I want this so I could see if showItems is checked which would alow me to perform the proper functions
i think i could do something like this
if($this.id = "withones"){
var withones = true;//on
}
if($this.id = "withoutOnes"){
var withoutOnes = true;//on
}
etc.
i feel like the above is a rookie way to code. lets say i have alot of checkboxes and it also looks like im repeating myself. I tried putting the ids in an array and loop through them but I got the html element in the console when i clicked on the box. I would like for someone to tell me if there is a more efficient way to set up these variables. and if so show me please.
Also I'm new to programming so thanks for your help so far. but I was also thinking about another problem. if I set up these variables here and I want to set up another function somewhere else to perform mathematical operations perse. i want that function to be able to evaluate the value of the withones and withoutOnes variables so I would like to do something like this in the function
function add(){
if(withones){ //true|| false
return 2 + 2;
}
if (withoutOnes) {
return 'blah'
};
}
I have had problems in the past trying to test the values that are set outside the function. I think i tried setting it in the arguments. but it just didn't read. If you could also show me an example of using the variables some where else in the code like discussed above that will be helpful . I forgot to mention that the value of the variable will change when the user clicks on the box. either to true or false. I think my problem in the past is that when the box is checked and then uncheck I had a problem changing the variable especially when it is being used in a separate function
}
});
});
You can have an object with your vars and add vars to that object dinamically:
var oVars = {}
// adding a var
oVars[nameVar] = valueVar
// accessing the var
oVars[nameVar]
You can capture the id with the attr() or you can just change the value of the checkbox with val() method in jQuery like this: FIDDLE
$(document).ready(function () {
$('.checkboxes').change(function (event) {
if ($(this).is(':checked')) {
var captureId = $(this).attr('id');
$(this).val(true);
alert($(this).val());
}
else {$(this).val(false);
alert($(this).val());}
});
});
Note that you can evaluate later all the checkboxes with one button and collect the value false or true from them. Why would you go through all of the complications with changing values of variables.
The other two answers are correct, though it sounds like you're wanting to know generally how to manage a big list of checkboxes with differing methods depending on type. It could look like this:
function multiply(this_object){
if((this_object.is(':checked')) && (this_object.attr("with") == 1))
return "with withone and checked";
else
return "is not both";
}
$(document).ready(function(){
$('.checkboxes').click(function(){
var this_object = $(this);
alert(multiply(this_object));
});
});
There should be no need to store all of the values in a variable unless you are passing all of them to another page - eg., via AJAX. Just reference them straight from the source field. If you need other info stored alongside, make a new attribute on the field - like the "with" one that I made for this example. See this Fiddle: http://jsfiddle.net/6ug6gL97/
your question is quite broad; so I’ll try to do my best to give you some kind of answer. First of all I’d use variables of global scope when declaring variables: withones and withoutOnes. Secondly, you wanted to avoid repetition in your code. Well, for that purpose I’d use JavaScript Arrays. In an array, you can add your variables as objects. In an object you can have your ids and other data “packed” neatly in the array, which in turn helps your code to become efficient.
Below is an array with objects:
objectArray = [{
id: "withones",
checked: false,
method: function () {
return 2 + 2;
}
}, {
id: "withoutOnes",
checked: false,
method: function () {
return 'blah';
}
}];
The above array can be used in your $('.checkboxes :checkbox').click(function() handler and add() function to avoid repetition. The updated code is below where jQuery's each() method is used for looping Array elements.
The last a bit of your question was related to add() function. Well, this was the tricky bit of your question, and I tried to use a callback function hopefully in the right way to execute your functions from the array. In the add method I tried to follow this answer: https://stackoverflow.com/a/13343452/2048391
About the last bit I’m not 100% sure did I use a callback function in the right way; so I hope someone more familiar with these tricky JavaScript functions can correct me, if something needs to be changed –thanks.
objectArray = [{
id: "withones",
checked: false,
method: function () {
return 2 + 2;
}
}, {
id: "withoutOnes",
checked: false,
method: function () {
return 'blah';
}
}];
$(document).ready(function () {
$('.checkboxes :checkbox').click(function () {
var id = this.id;
var checkedValue = this.checked;
$.each(objectArray, function (index, object) {
if (object.id === id) {
object.checked = checkedValue;
}
});
add();
});
function add() {
// clear results
$("#addResults").text("");
$.each(objectArray, function (index, object) {
if (object.checked === true) {
var returnValue = createCallback(object.method)
$("#addResults").append(returnValue + "<br>");
console.log(returnValue);
}
});
}
function createCallback(method) {
return method();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="checkboxes">
<input type="checkbox" id="withones"></input>
<label>With Ones</label>
<br>
<input type="checkbox" id="withoutOnes"></input>
<label>Without Ones</label>
</div>
<div id="addResults">
</div>

Getting "This" into a namespace in Javascript

I'm sure this should be a simple question but I'm still learning so here it goes:
I have some code to run a function on click to assign the clicked element's ID to a variable but I don't know how to pass the "this.id" value to the namespace without making a global variable (which I thought was bad).
<script>
fsa = (function() {
function GetTemplateLoc() {
templateId = document.activeElement.id;
alert(templateId + templateId2);
}
return {
GetTemplateLoc: GetTemplateLoc,
}
})();
//call the functions
$(document).on('click', '.template', function () {
fsa.GetTemplateLoc();
});
</script>
and HTML with random picture:
<img id="template-1" class="template" src="http://fc02.deviantart.net/fs70/f/2010/028/c/b/cb21eda885b4cc6ee3f549a417770596.png"/>
<img id="template-2" class="template" src="http://fc02.deviantart.net/fs70/f/2010/028/c/b/cb21eda885b4cc6ee3f549a417770596.png"/>
The following would work:
var fsa = (function() {
function GetTemplateLoc() {
var templateId = this.id;
alert(templateId);
}
return {
GetTemplateLoc: GetTemplateLoc,
}
})();
//call the functions
$(document).on('click', '.template', fsa.GetTemplateLoc);
jQuery generally calls functions you pass as event handlers with this set to the DOM object the event is associated with.
In this case it will call GetTemplateLoc() with this set to either .template element, so you can use this directly in the function and don't need to pass any parameters.
Important tip: Always declare variables using var. JavaScript has no automatic function-local scope for variables, i.e. every variable declared without var is global, no matter where you declare it. In other words, forgetting var counts as a bug.
Try this : You can directly use this.id to pass id of the clicked element where this refers to the instance of clicked element.
<script>
fsa = (function() {
function GetTemplateLoc(templateId ) {
//templateId = document.activeElement.id;
alert(templateId + templateId2);
}
return {
GetTemplateLoc: GetTemplateLoc,
}
})();
//call the functions
$(document).on('click', '.template', function () {
fsa.GetTemplateLoc(this.id);
});
</script>
If you're able to use jQuery within the GetTemplateLoc function, you could do something like this:
var fsa = (function() {
function GetTemplateLoc($trigger) {
var templateId = $trigger.attr('id'),
templateId2 = $($trigger.siblings('.template')[0]).attr('id');
alert(templateId + ' ' + templateId2);
}
return {
GetTemplateLoc: GetTemplateLoc,
}
})();
$(document).on('click', '.template', function () {
fsa.GetTemplateLoc($(this));
});
You can set GetTemplateLoc to expect a jQuery object as a parameter (the dollar sign at the beginning of $trigger can be used to distinguish it as a jQuery object rather than any other data type, it's not necessary but can help clarify things sometimes).
templateId will store the value of the clicked image's ID, and templateId2 will store the value of the other image's ID. I also added a space between the two variables in the alert.
If you can't use jQuery within GetTemplateLoc, you could do something like this:
var fsa = (function() {
function GetTemplateLoc(trigger) {
var templateId = trigger.id;
var templateId2 = trigger.nextElementSibling == null ? trigger.previousElementSibling.id : trigger.nextElementSibling.id;
alert(templateId + ' ' + templateId2);
}
return {
GetTemplateLoc: GetTemplateLoc,
}
})();
This time, the .template that triggered the event is passed into GetTemplateLoc, but this time it's not a jQuery object. templateId is assigned to the trigger's ID and then templateId2 is assigned in a ternary. First, the nextElementSibling of trigger is checked to see if it's null. If it is, we know that trigger is the second of the two .template elements. Therefore we can set templateId2 to the ID of trigger's previous sibling. If trigger's nextElementSibling is not null, then we know that trigger is the first template and we populate templateId2 with the ID of nextElementSibling. This exact method will only work with two .template's, if there are more you'll need some additional/different logic, probably to retrieve all .template IDs and then loop through them to add them to the alert message. Hope this helps.

How to get selector's variable on Onclick

When a selector is assigned to a variable, I need to get that variable name on onclick I have created a Fiddle as an example
var $main_img1 = $("<div/>").addClass('add1').appendTo($('#main_container'));
var $main_img2 = $("<div/>").addClass('add2').appendTo($('#main_container'));
$main_img1.click(function()
{
get_id()
});
$main_img2.click(function()
{
get_id()
});
function get_id(event)
{
console.log($(this))
alert('i need to get selector variable on click')
}
Output should be $main_img1 and $main_img2 when I click on the corresponding div
Here is a solution, but not sure how you are going to use it
Used Array to get the variable name.
JS
var arr = new Array();
arr[0] = '$main_img1';
arr[1] = '$main_img2';
var $main_img1 = $("<div/>").addClass('add1 add').appendTo($('#main_container'));
var $main_img2 = $("<div/>").addClass('add2 add').appendTo($('#main_container'));
$main_img1.click(function()
{
get_id($(this))
});
$main_img2.click(function()
{
get_id($(this))
});
function get_id(event)
{
alert(arr[$('.add').index(event)]);
}
Update : No array needed.
function get_id(event)
{
///var temp = '$main_img' + (parseInt($('.add').index(event)) + 1);
var temp = '$main_img' + (parseInt($('#main_container > div').index(event)) + 1);
alert(temp);
console.log(eval(temp));
}
Updated DEMO
I suggest a workaround.. see if it helps you. Add a hidden element inside the corresponding divs and add the variable names as text to it. I slightly modified your method get_id() to get the variable name from your divs hidden element.
function get_id()
{
console.log($(this))
var selVar= $(this).parent().find('input:hidden:first').text();
alert('selector variable' + selVar);
}
this will work for you.
You could maybe guessing from the class of the element you click on it and use reflexivity.
To know the element you click on it, just use event.target where event is a variable passed in the click function. Look at this fiddle for an example.
The get_id method now looks like this:
function get_id(event) {
console.log(event.target)
}
The value returned by event.target is the same as the value returned by the variable you declare it ($main_img1 or $main_img2).

jQuery global selection "cache"

I don't think I'm the first one to run into this issue but I haven't find a way to search for this without getting results that have nothing to do with the issue.
I adopted the not so extended good practice of "caching" repetitive jQuery selections into vars like var element = $('#element'); to prevent "DOM pool searching" for every repeated use of the element
The problem I'm having is that now I'm doing this caching inside a function. Something like:
function functionname (id) {
var id = $('#'+id);
//extra stuff
}
I'm not expert in variables scopes but I'm not being able to do
functionname ('some-div-id');
some-div-id.dialog('open');
So I'm pretty sure it's because the variable created inside the function is not accesible outside the function itself.
Then I came up with
function functionname (id) {
window.id = $('#'+id);
//extra stuff
}
but if I try to do window.some-div-id.dialog('open'); I get TypeError: 'undefined' is not a function
What am I missing? I'm sure it's a small dumb thing but I'm missing it just in front of my eyes.
Thanks
EDIT
Thanks everyone but you're missing something.
The code suggestions are missing the fact that the inside "global" variable name is dynamic:
var CACHEobject = {};
function doSomething (NAMEHERE) { //note the function parameter
CACHEobject.NAMEHERE = $('#'+NAMEHERE);
}
So the idea is that the function creates a javascript variable with the same name that the #element_id. If I pass a name to the function it should select the html id with that name and "cache it" to a global variable with the same name:
doSomething('myDialogOne'); doSomething('myDialogTwo');
so I can later do
CACHEobject.myDialogOne.dialog('open'); CACHEobject.myBox.dialog('close');
This is what you want (based off the edit):
var CACHEobject = {};
function doSomething(id) {
CACHEobject[id] = $('#' + id);
}
Your idea is fine. Just set up an object for that. Here's an example using STASH as the caching object:
<html>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
var STASH = {};
$(document).ready(function(){
// stash your elements
STASH.item = $('#item');
STASH.otherItem = $('#otherItem');
// do stuff to them
STASH.item.css({
color: '#f00'
}); // sets #item to red
alert(STASH.otherItem.text()); // alerts foo
});
</script>
<style></style>
<body>
<div id="item">bar</div>
<div id="otherItem">foo</div>
</body>
</html>
window.some-div-id.dialog('open');
is interpreted as:
window.some - div - id.dialog('open');
i.e. subtracting, which causes three undefined variables, one of which is id.dialog which causes an error when trying to be executed as a function.
For special characters, use:
window["some-div-id"].dialog('open');
And to define:
window[id] = $("#" + id);
Anyhow, I would not advise you to use global variables. You'd better overwrite the jQuery function to implement caching (using an object with the selector as key and the matched element as value).
You could just declare the variable outside the function.
var $foo;
function some_function(id) {
$foo = $('#' + id);
}
function setDialog(selector) {
window.$dialogElem = $(selector);
//window.dialogSelector = selector;
}
var id= 'mensajes';
setDialog('#'+id);
window.$dialogElem.dialog();
//$(window.dialogSelector).dialog();
commented stuff is an alternative that takes less memory. But why the hell use window?? check this fiddle for various simple techniques.

Categories

Resources