How to use parameters from another function [duplicate] - javascript

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Get actual HTML values using javascript
so i have two problems here. let me explain what i am trying to do first. I have a page that has values that change on it, however i want to grab the values before they change, keep them, and then once a button is pushed, change the html to the original html. Now first of all my biggest problem is that when i try to uncomment the initial2 function, it just doesnt work. it brings me to the webpage then for some reason the html url tries to change and it says it can not find the page. the second, and more understandable problem for me, is that the function previousaccept i cant get to use the values from the previousnames function.
function previousnames()
{
name= document.getElementById('name').innerHTML;
imagetitle= document.getElementById('imagetitle').innerHTML;
location=document.getElementById('location').innerHTML;
similarities = document.getElementById('similarities').innerHTML;
type = document.getElementById('type').innerHTML;
cost = document.getElementById('cost').innerHTML;
date = document.getElementById('date').innerHTML;
pictureid = document.getElementById('pictureid').src;
}
function previousaccept(name,imagetitle,location,similarities,value,type,cost,date,pictureid)
{
document.getElementById('name').innerHTML = name;
document.getElementById('location').innerHTML = location;
document.getElementById('similarities').innerHTML = similarities;
document.getElementById('type').innerHTML = type;
document.getElementById('cost').innerHTML = cost;
document.getElementById('date').innerHTML = date;
window.alert(pictureid);
document.getElementById('pictureid').src = pictureid;
}
window.onload=initial();
function initial()
{
myvalues;
previousnames;
}
/*
function initial2()
{
myvalues;
previousnames();
}*/

If you set the location (which is window.location), then the browser will go to a new web page. That's what you're doing in the previousnames() function with this line:
location=document.getElementById('location').innerHTML;
If you're trying to have a global variable named location, then give it a different name that isn't already used by the browser.
Also, you should explicitly declare any global variables you intend to use outside of your functions rather than use implicitly declared variables like you are which makes your code very prone to errors.

I think this will do what you want. The key is to make sure that the scope of the variables you are trying to store is such that the functions have access to them all. I do this by defining an empty object dataStore at the start of the onload function, and also defining the 2 other functions within the onload function. Putting all the stored data in a single object is convenient and avoids naming problems (such as the window.location problem noted by the previous answer.)
window.onload = function() {
var dataStore = {};
function getInitialData() {
dataStore = {
name: document.getElementById('name').innerHTML,
imagetitle: document.getElementById('imagetitle').innerHTML,
// and so on...
}
}
function resetData() {
document.getElementById('name').innerHTML = dataStore.name;
document.getElementById('imagetitle').innerHTML = dataStore.imagetitle;
// and so on...
}
getInitialData();
//... then later when you want to reset all the values
resetData();
}​

Related

How to use a variable as a function parameter in Javascript?

I'm a big noob at JS,so if my question is hard to understand then sorry😂.
I'm writing a program in JS(Electron) that provides a user interface for another program I made in C++, so I'm basically rewriting it in JavaScript.
I want to use this JSON variable(or whatever it's called) in my code.
var ShowSecondsInSystemClock = '{"name":"ShowSecondsInSystemClock","Description":"Patches the System Tray clock to show seconds","ExplorerRestartRequired":"true","category":"UI-Tweaks","badges":"UITweaks"}'
Then I would like to use this function where the parameter of the function "ShowSecondsInSystemClock" is.
function TweakParser(TweakName, NeeddedReturn) {
if (NeeddedReturn == "Description") {
//I'm trying to use TweakName as the parameter of parse(),but it only
//accepts the name of the Tweak directly
var NeeddedTweakInfo = JSON.parse(TweakName)
return NeeddedTweakInfo.Description
}
}
Because there will be many Tweaks, the usecase of this particular function is for example
//I use a non-existing tweak here for the example
TweakParser("RemoveArrowsFromShortcut","Description")
What I want TweakParser to do now is use RemoveArrowsFromShortcut as the parameter of JSON.parse() but it only accept the name of the JSON variable directly and when I input the name of the first parameter of the TweakParser() function it gives me an error, because the parameter(a variable) itself is not a JSON variable (or whatever it's called like).
So my question to you is:
How can I use the string that the first parameter of TweakParser() contains as a parameter for the JSON.parse() function?
You need to create mapping
like a schema 'key': variable
example:
{
'RemoveArrowsFromShortcut': ShowSecondsInSystemClock
}
Full example:
var ShowSecondsInSystemClock = '{"name":"ShowSecondsInSystemClock","Description":"Patches the System Tray clock to show seconds","ExplorerRestartRequired":"true","category":"UI-Tweaks","badges":"UITweaks"}'
var mapping = {
RemoveArrowsFromShortcut: ShowSecondsInSystemClock
};
function TweakParser(TweakName, NeeddedReturn) {
if (NeeddedReturn == "Description") {
var NeeddedTweakInfo = JSON.parse(mapping[TweakName]); // PAY ATTENTION HERE
return NeeddedTweakInfo.Description
}
}
var result = TweakParser("RemoveArrowsFromShortcut","Description")
console.log('result', result)

Assign custom property to dynamically generated JS functions

I'm trying to setup a speed test for functions. It works when I pass in a function directly, but I'd like to offer co-workers a form to cut and paste their own.
function sendTest() {
//fName, fContent
var fName = document.getElementById("fName").value;
var fContent = document.getElementById("fContent").value;
var f = new Function(fName, fContent);
f.name = fName;
testTime(f);
}
testTime() is the function to evaluate performance, and evaluating time of execution is working correctly from sendTest(), but I can't access the function name from testTime() to display the function name with the results. f.name and f.fName both come up as undefined.
A function is an object, right? So I should be able to apply a name propery to it?
This seems like a much simpler answer for your specific problem than the what someone else marked your question a duplicate of.
In ES6, there is a built-in .name property of a Function which is NOT writable so that's why you can't assign to it (link to specific section of draft ES6 spec). You should be able to use a different property name if you want to assign a name the way you are doing so.
Working demo using a different property name: http://jsfiddle.net/jfriend00/6PVMq/
f = new Function("log('Hello')");
f.myName = "sayHi";
function testFunc(func) {
log("function name is: " + func.myName);
func();
}
testFunc(f);

How can I avoid using eval() for the base object

As I understand it, eval() can be harmful. And it's annoying seeing all the warnings in my JSLint.
I've got a number of functions that are identical for my Wishlist / Shopping Cart. So I'd like to make it dynamic and only have one function of each.
Instead of cart.addItem() and wish.addItem(), I want cartWish.addItem(type).
Inside of cartWish.addItem() I need to access cart.data or wish.data, depending on the type argument.
How can I do this without resorting to eval(type).data?
I tried this[type].data and it didn't seem to work right.
What's the difference between
cart.addItem(...);
wish.addItem(...)
and
cartWish.addItem("cart", ...);
cartWish.addItem("wish", ...);
Seems like the same number of lines of code, and then all you've done is obfuscate what you are really doing. Maybe create a function that takes either a cart or wish object and assume they have the same interface:
function addItem(x, data) {
x.addItem(data);
}
var cart = ...
var wish = ...
addItem(cart, {...});
addItem(wish, {...});
Another option is to create a class:
function Item(type) {
this.type = type;
}
Item.prototype.add = function add(...) {
// ...
};
var cart = new Item("cart");
var wish = new Item("wish");
cart.add(...)
wish.add(...)
It was poor programming on my part. I didn't know that JavaScript tended to make references of objects instead of copies.
So doing...
var myReference=(type == "cart") ? cart.data : wish.data;
myReference[0].name="Bob Dole's Grill";
... will actually change cart.data[0].name outside of the function. And it will do so without making a copy of the cart object in memory.
Note: You could also just pass in the object by reference into the function, but I'm not sure if I can, because I'm sometimes invoking this function from a KnockoutJS click event.

About a loop that creates dynamic buttons, but cannot give proper values [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript infamous Loop problem?
I am having a small issue, and it would be very nice if some of you could realize about what kind of logic is missing here, since I cannot seem to find it:
I have an array with the results of some previous operation. Let's say that the array is:
var results = [0, 1];
And then I have a bunch of code where I create some buttons, and inside a for loop I assign a different function to those buttons, depending on the position of the array. The problem is that for some reason, all the buttons created (two in this case) come out with the function assigned to the last value of the array (in this case, both would come out as one, instead of the first with 0 and the second with 1)
This is the code:
for (var i = 0; i < results.length; i++) {
var br2 = b.document.createElement("br");
var reslabel = b.document.createTextNode(Nom[results[i]].toString());
var card = document.createElement("input");
card.type = "button";
id = results[i]; // this is the problematic value.
card.onclick = newcard; // this function will use the above value.
card.value = "Show card";
divcontainer.appendChild(br2);
divcontainer.appendChild(reslabel);
divcontainer.appendChild(card);
}
As it is, this code produces as many buttons as elements in the array, each with its proper label (it retrieves labels from another array). Everything is totally fine. Then, I click the button. All the buttons should run the newcard function. That function needs the id variable, so in this case it should be:
First button: runs newcard using variable id with value 0
Second button: runs newcard using variable id with value 1
But both buttons run using id as 1... why is that?
It might be very simple, or maybe is just that in my timezone is pretty late already :-) Anyways, I would appreciate any comment. I am learning a lot around here...
Thanks!
Edit to add the definition of newcard:
function newcard() {
id = id;
var toerase = window.document.getElementById("oldcard");
toerase.innerHTML = "";
generate();
}
the function generate will generate some content using id. Nothing wrong with it, it generates the content fine, is just that id is always set to the last item in the array.
Your id is a global variable, and when the loop ends it is set to the last value on the array. When the event handler code runs and asks for the value of id, it will get that last value.
You need to create a closure to capture the current results[i] and pass it along (this is a very common pitfal, see Javascript infamous Loop problem?). Since newcard is very simple, and id is actually used in generate, you could modify generate to take the id as a parameter. Then you won't need newcard anymore, you can do this instead:
card.onclick = (function(id) {
return function() {
window.document.getElementById("oldcard").innerHTML = "";
generate(id);
};
}(results[i]));
What this does is define and immediately invoke a function that is passed the current results[i]. It returns another function, which will be your actual onclick handler. That function has access to the id parameter of the outer function (that's called a closure). On each iteration of the loop, a new closure will be created, trapping each separate id for its own use.
Before going on, a HUGE thank you to bfavaretto for explaining some scoping subtelties that totally escaped me. It seems that in addition to the problems you had, you were also suffering from scoping, which bit me while I was trying to craft an answer.
Anyway, here's an example that works. I'm using forEach, which may not be supported on some browsers. However it does get around some of the scoping nastiness that was giving you grief:
<html>
<body>
<script>
var results = [0,1];
results.forEach( function(result) {
var card = document.createElement("input");
card.type = "button";
card.onclick = function() {
newcard( result );
}
card.value = "Show card";
document.body.appendChild(card);
});
function newcard(x) {
alert(x);
}
</script>
</body>
</html>
If you decide to stick with a traditional loop, please see bfavaretto's answer.

JSON how find another value at the same index from a value in Javascript Object

A simple question I'm sure, but I can't figure it out.
I have some JSON returned from the server
while ($Row = mysql_fetch_array($params))
{
$jsondata[]= array('adc'=>$Row["adc"],
'adSNU'=>$Row["adSNU"],
'adname'=>$Row["adname"],
'adcl'=>$Row["adcl"],
'adt'=>$Row["adt"]);
};
echo json_encode(array("Ships" => $jsondata));
...which I use on the client side in an ajax call. It should be noted that the JSON is parsed into a globally declared object so to be available later, and that I've assumed that you know that I formated the ajax call properly...
if (ajaxRequest.readyState==4 && ajaxRequest.status==200 || ajaxRequest.status==0)
{
WShipsObject = JSON.parse(ajaxRequest.responseText);
var eeWShips = document.getElementById("eeWShipsContainer");
for (i=0;i<WShipsObject.Ships.length;i++)
{
newElement = WShipsObject.Ships;
newWShip = document.createElement("div");
newWShip.id = newElement[i].adSNU;
newWShip.class = newElement[i].adc;
eeWShips.appendChild(newWShip);
} // end for
}// If
You can see for example here that I've created HTML DIV elements inside a parent div with each new div having an id and a class. You will note also that I haven't used all the data returned in the object...
I use JQuery to handle the click on the object, and here is my problem, what I want to use is the id from the element to return another value, say for example adt value from the JSON at the same index. The trouble is that at the click event I no longer know the index because it is way after the element was created. ie I'm no longer in the forloop.
So how do I do this?
Here's what I tried, but I think I'm up the wrong tree... the .inArray() returns minus 1 in both test cases. Remember the object is globally available...
$(".wShip").click(function(){
var test1 = $.inArray(this.id, newElement.test);
var test2 = $.inArray(this.id, WShipsObject);
//alert(test1+"\n"+test2+"\n"+this.id);
});
For one you can simply use the ID attribute of the DIV to store a unique string, in your case it could be the index.
We do similar things in Google Closure / Javascript and if you wire up the event in the loop that you are creating the DIV in you can pass in a reference to the "current" object.
The later is the better / cleaner solution.
$(".wShip").click(function(){
var id = $(this).id;
var result;
WShipsObject.Ships.each(function(data) {
if(data.adSNU == id) {
result = data;
}
});
console.log(result);
}
I could not find a way of finding the index as asked, but I created a variation on the answer by Devraj.
In the solution I created a custom attribute called key into which I stored the index.
newWShip.key = i;
Later when I need the index back again I can use this.key inside the JQuery .click()method:
var key = this.key;
var adt = WShipsObject.Ships[key].adt;
You could argue that in fact I could store all the data into custom attributes, but I would argue that that would be unnecessary duplication of memory.

Categories

Resources