What I want in html code:
<a onclick="DeleteImage('javascript:this.id', <?=$_SESSION['UserID']?>)"></a>
which passes the var userid from $_session to the javascript function:
function DeleteImage(aid,userid){}
This worked when i didnt had to pass the $_session variable and only had this function
function DeleteImage(aid){}
Then i could create the a element in javascript like this:
cross = document.createElement('a');
cross.onclick = function() { DeleteImage(this.id) };
How can I create the a element so it generates the html code i want?
I want something like:
cross.onclick = function() { DeleteImage(this.id, "<?=$_SESSION['UserID']?>") };
which obviously does not work. Any help appreaciated :)
I think you should change the way you retrieve an information like $_SESSION['UserID']. An interesting option would be creating a data attribute, for example in the <html> tag itself:
<html data-user-id="<?=$_SESSION['UserID']?>">
Then all you have to do is to retrieve that value in the DeleteImage function itself:
function DeleteImage(aid) {
var userId = document.documentElement.getAttribute("data-user-id");
...
}
And you're done, you can call DeleteImage with the old way. (Note: you can also use document.documentElement.dataset.userId in Chrome, Firefox and Opera. There are partial polyfills for IE, but I guess they're not worth the effort in your case.)
You can even save some extra cycles retrieving the value at the beginning of the script and storing it in a scoped variable:
var userId = document.documentElement("data-user-id");
function DeleteImage(aid) {
...
}
Slightly off topic, may I suggest to using some more modern way to attach event listeners? And maybe considering some kind of event delegation?
Related
There are several elements on HTML page which triggers a js function HardCoded().
I cannot modify HardCoded() function.
I want to run some custom js code after the HardCoded() function is getting called. How can I do that? Is there any handlers for js functions?
I'm building a chrome extension that's why I cannot modify page source code.
I have access to JQuery.
One way is to find all elements who are calling HardCoded() and attach events to those elements but I would like to avoid this method.
You could do something like this:
var oldFn = HardCoded;
window.HardCoded = function(){
var res = oldFn.apply(this, arguments);
// New Code ....
return res;
}
What this does is to create a reference to the HardCoded function, redefine this function and then call the old implementation using the previously created reference.
Thanks in advance for the help.
I am trying to monkeypatch an existing javascript function so that one of its lines point to a new location. It would be easy to just redefine the function, except that it is rendered from server side code that has dynamic contents in it.
function GoPrint() {
$.cookie('edit_child','on',{expires:28,path:'/'}); //Dynamically created (edit child could be off)
window.open('../../Common/Output/HTMLtoPDF.aspx','print'); //Always static, need to change this call.
}
In my example, the first line creating the cookie, is created dynamically server side, so the property could be set to off.
I need to the change the window.open to call a different page instead of the htmltopdf page.
Although nasty, I would like to just redefine the function with a replace on the HTMLtoPDF text to point to the new page.
I have started this below, but do not know how to get the existing contents of the function to change it.
function($){
var _oldPrint = $.fn.GoPrint;
$.fn.GoPrint = function(arg1,arg2){
return _oldPrint.call(this,'',);
};
})(jQuery);
Any suggestions?
One way to do it would be to call toString on the old function, sub the old URL out with the new one, and eval the result, but only after considering the security implications.
Purely security-wise, a safer way would be to monkey patch the window.open function inside the monkey patch of GoPrint.
function($) {
var _oldPrint = $.fn.GoPrint;
$.fn.GoPrint = function(arg1, arg2) {
var _oldopen = window.open;
window.open = function() {
_oldopen.call('YOUR_URL_HERE', 'print');
};
return _oldPrint.call(this);
window.open = _oldopen;
};
})(jQuery);
Ok, I just stepped into something tricky. I need to fire an event on my app everytime a major update happens (because I want multiple windows opened, therefore they need to be updated). The thing is, with that event, I wish to pass an argument, something like this:
Ti.App.fireEvent('updateViews', {data: my_data});
So far so good, but when I receive this event I want to be able to access its data. The only way I found out to do so is to create an anonymous function, like this:
Ti.App.addEventListener('updateViews', function(data)
{
var name = data.name;
});
Great! That works! Now the big problem.. when I close this window, I need to remove that listener... Otherwise I'll end up with a memory leak. The thing is, if I change the anonymous function and pass it to a handler, I'm unable to access the data - but if I don't, I cant reference the function to successfully remove it. Please, help!
PS: There IS a way to do this, of course I could pass the data using Alloy.Globals (or the equivalent in the standard Ti), but I want a CLEAN, elegant solution that does not involve using Alloy.Globals. Thanks in advance.
Is there a reason you need to use global app events? They make code more difficult to maintain and result in tighter coupled dependencies that are brittle when something changes. It also increases side effects when attempting to understand the code (Your future self will forget and you will get lost and confused).
The problem your experiencing is probably from the assumption that by assigning to a data property that it becomes the argument. The object you pass into fireEvent will be the object passed to the callback argument.
Ti.App.fireEvent('updateView', {data: {name: "foo"}});
Ti.App.addEventListener('updateView', function(e) {
var name = e.data.name;
});
That being said, events in general can easily pass data via the fireEvent as you demonstrated. I find in cases of 'click' events I'm more interested in static data then in dynamic data. I use partial applications for this: (example uses underscore provided by Alloy, but the functionality can easily be polyfilled)
var _ = Alloy._;
var titles = ['foo', 'bar', 'baz'];
var messages = [
'This ia s foo message.',
'But a bar message is better.',
'Then again a baz message trumps them all.'
];
function onClick(message, e) {
e.cancelBubble = true; // Not required but shows how to access the event object
alert(message);
}
var tableData = _(titles).map(function(title, index) {
var row = Ti.UI.createTableViewRow({title: title});
row.addEventListener('click', _.partial(onClick, messages[index]));
return row;
});
var table = Ti.UI.createTableView({
data: tableData
});
So.. I figured it out. You can actually do that.. The problem was that I was registering the handler the wrong way. It will work if you just only set the handler to receive data. Example for the above code:
var handler = function(data) {
var name = data.name;
alert(name);
}
Ti.App.addEventListener('updateViews', handler);
Then, to remove it:
Ti.App.removeEventListener('updateViews', handler);
What Im trying to do is to get the content of a specific textarea tag in a specific clicks of a button, so I think a loop will solve this problem. The while loop on PHP does the role of making the name of textarea different and button's onclick trigger. But the loop in javascript wont work. Please anyone help what is the right one to complete my task?? Sorry for bad english...Thanks in advance
<html>
<head>
<script>
var i = 0;
while(i < 2000)
{
i++;
function feedbacks+i()
{
var feed = document.getElementsByName("feedback"+i)[0].value;
alert(feed);
}
}
</script>
</head>
<body>
<?php
while($i < 2000)
$i++;
echo "<textarea name='feedback$i' >you post</textarea>";
echo "<button onclick='feedbacks$i()' >send feedback</button>";
?>
</body>
</html>
I'm not sure if i get your question right, but why don't you write one single javascript function and pass the index as a parameter?
like:
function feedbacks(index) {
var feed = document.getElementsByName("feedback"+index)[0].value;
alert(feed);
}
and
onclick='feedbacks($i)'
Your code is incorrect, Since you have tagged your question with Jquery, I would like to suggest the following solution,
$(document).ready(function(){
$(document).on('click','button',function(){
alert($(this).prev('textarea').val())
});
});
You are creating those elements textarea and the button in runtime, So you have to use delegation inorder to register the click event for those buttons. Additionally you have to wrap your code inside .ready() function, Which means you have to manipulate the DOM only after it got ready.
Please see here for references,
.on (for delegation)
.ready()
.prev()
You have two major problems here.
Naming your function
When you name a function, you can't use variables, only a single identifier.
You could use a function expression and then assign the result somewhat that you can identify with a variable. e.g.
an_array_i_created_earlier[i] = function () {
// etc etc
}
Closures
You are trying to use i inside the function you are creating, but you are changing it outside that function before that function runs.
You can get around this by creating a new closure.
function createFunction(i) {
return function () {
// can use i sanely here because it was passed into a local variable belonging to `createFunction`
};
}
an_array_i_created_earlier[i] = createFunction(i);
This is all very messy though. You can forget about having to deal with i entirely, and throw out the horribly intrinsic event attributes while you are at it. Instead, navigate through the DOM to find the element:
addEventListener('click', function (evt) {
var textarea, t = evt.target;
if (t.classList.contains('feedback')) {
textarea = t.previousElementSibling;
alert(textarea.value);
}
});
Note that this uses some fairly recent additions to browser DOM. If you want compatibility with older browsers (in particular IE9 and earlier) then you will probably want to rewrite it to add some support for legacy approaches. A library like YUI or jQuery can help with that.
There's some error in your JavaScript code:
You tried to define a sequence of functions in a loop, and the function became local function to that loop. You cannot get access to these functions outside the loop. In order to make this work, you should define the function on window object, with the syntax window["feedbacks1"] = function () {}.
function feedbacks+i() is invalid syntax, use window['feedbacks' + i], as pointed in (1).
Functions defined in loop will share some local variable (closure). The variable in the function feedbacks#{i} will all share the same i. After the loop, i became 2001 and all the functions defined will try to get textarea with name feedbacks2001, which of course will not work. You will need the (function (i) { /* the code using i */ })(i); trick to make a local copy of the shared variable.
I made a demo on jsFiddle which correct the mistakes. I showed only 2 textareas. The following javascript should work for you 2000 textareas case.
for (var i = 0; i <= 2; ++i) {
window["feedbacks" + i] = (function (i) {
return function (e) {
var feed = document.getElementsByName("feedback"+i)[0].value;
alert(feed);
};
})(i);
}
My query is regarding using Javascript to change the value of an onclick function that already exists on the page.
There's a button. This button has the following onclick function:
onclick="if (confirm('Yahdy Yahdy yah?')) { someFunction(); }; return false;"
I would like to change the onclick function using Javascript to just be as follows and or extract the someFunction(); and run that directly without having to go through the confirmation. As I understand it, you can't confirm a confirm through scripting, so my only option is to run someFunction(); directly. My question is, how do I access someFunction() directly as someFunction() contains randomly generated values each time the page loads.
onclick="someFunction();"
That's basically what I'd like, so I can then call onclick() directly. I'm happy to use vanilla or jQuery to go about this.
TLDR: I want to extract PART of the old onclick function and make a new onclick function with JUST that part.
You can do this:
var code = obj.onclick.toString();
That will give you the javascript code assigned to that click handler to which you can search through it, find what you're looking for and reassign the click handler to something else.
I have no idea if this is the best way to do it, but here's something that worked for me:
function nullConfirm() { return true;};
(function() {
var obj = document.getElementById("test");
var code = obj.onclick.toString();
code = code.replace("confirm(", "nullConfirm(");
var matches = code.match(/\{(.*)\}/);
if (matches) {
obj.onclick = function() {
eval(matches[1]);
}
}
})();