Can't get the id name using onClick? - javascript

http://wthdesign.net/test/test.html
What I'm trying to do is append the id name into my url, but I'm getting "#undefined" instead?
The script I'm using:
function generateUrl()
{
var currentId = $(this).attr('id');
document.location.hash = currentId;
console.log($(this));
}
inside the html:
<a id="abc" onClick="generateUrl()" >this is an anchor btn</a>

<a id="abc" onClick="generateUrl(this)" >this is an anchor btn</a>
function generateUrl(elem)
{
var currentId = elem.id;
document.location.hash = currentId;
}
You pass the element to your function with "this"

If you debug, you'll find that this in this context is the window object. You can pass this into the function like so:
function generateUrl(el)
{
var currentId = $(el).attr('id');
document.location.hash = currentId;
}
<a id="abc" onClick="generateUrl(this)" >this is an anchor btn</a>
Alternatively, you can use jquery to replace your inline onClick like so:
$("#abc").click(function()
{
var currentId = $(this).attr('id');
document.location.hash = currentId;
}

That's because setting onclick HTML attribute is equivalent to set an anonymous function like this:
element.onclick = function(event) {
generateUrl();
}
As you can see, in your call you lost both event object and this contextual object, that becomes the global ones (window for the browsers).
Then you have several approach. First, don't use the HTML attribute, but set the click by JS instead, that is a better practice – avoid spaghetti code, when it's possible.
You're using jQuery, therefore:
$(function() {
$("#abc").click(generateUrl);
});
Plus, your function can be simplified:
function generateUrl() {
window.location.hash = this.id;
}
So your HTML will be just:
<a id="abc">this is an anchor btn</a>
If, for any reason, you can't / don't want remove the onclick from the HTML, you have to modify it a bit:
<a id="abc" onClick="generateUrl.call(this)" >this is an anchor btn</a>
In that way you're calling the function passing the right contextual object. Just as future reference, you could also pass the event as first argument:
<a id="abc" onClick="generateUrl.call(this, event)" >this is an anchor btn</a>
P.S.
Notice that without an href attribute in your a tag, the browser won't threat that tag as a "link".

Related

Passing the correct context to a function with arguments from ready function

I have spent a day trying to find the way to pass the correct context to the removeForm. The goal is to use the removeForm which is called when pressing <a class="remove_2"> remove </a> link to remove the content of the class passed to removeForm in this case "subform2". Here is what I tried:
function removeForm(tgsubf) {
var $removedForm = $(this).closest(tgsubf);
var removedIndex = parseInt($removedForm.data('index'));
$removedForm.remove();
}
$(document).ready(function() {
$('.remove_2').click(function(e){
e.preventDefault();
removeForm('.subform2')
});
}
<div class="subform2">
<a class="remove_2"> remove </a>
</div>
I know that the context depends on how I call the function but also if I call the function using removeForm('subform2') I still have this problem.
The full example is hosted here.
If you want to remove the .subform2 element that contains the .remove_2 which was clicked, you can do the following.
When your are inside an event callback you pass to jQuery, this (generally) holds the element that received the event. So you should change your code to have the following:
$('.remove_2').click(function(e){
e.preventDefault();
removeForm(this) // <-- 'this' will refer to $('.remove_2')
});
Then you can change your removeForm() to get the immediate ancestor of the element passed to it (which would be .remove_2) that has .subform2 for class and remove it, like this:
function removeForm(anchor) {
var $removedForm = $(anchor).closest('.subform2');
$removedForm.remove();
}
UPDATE
You should be able to pass a selector to removeForm to identify the ancestor, like this:
function removeForm(el, ancestorSelector) {
// Do check to ensure ancestorSelector is provided, before using it.
var $removedForm = $(el).closest(ancestorSelector);
$removedForm.remove();
}
You can update how you call it like this:
$('.remove_2').click(function(e){
e.preventDefault();
removeForm(this, '.subform2') // <-- 'this' will refer to $('.remove_2')
});

Jquery on click not working while passing data

Question is very simple but due to some reason i am not able to fix it.
Here is the a href tag that will open modal box.
<center>Apply</center>
Here is jquery to get id from data attribute.
<script type="text/javascript">
$('document').ready(function()
{
$(document).on('click', '#btn-classified', function() {
//$("#btn-classified").on("click", function () {
//$("#btn-classified").click(function() {
var myvar1 = $(this).data('data');
alert(myvar1);
});
});
</script>
For some reason i am not getting any output if i use $(document).on('click', '#btn-classified', function() {
and if i use $("#btn-classified").on("click", function () { then i am getting undefined.
To get 'data' attribute of <a> element use .attr() function of jQuery
$('document').ready(function() {
$(document).on('click', '#btn-classified', function() {
var myvar1 = $(this).attr('data'); // .attr() to get attribute of an element
alert(myvar1);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href='#' id='btn-classified' data='This an element of DOM'>Get this DATA value</a>
Your Code get undefined on event click when your call to an element which exist after of the function.
You need performance the logic of your code, on jQuery you want use
$(document).ready(function(){
//your functions with selectors of DOM
})
or use .on() function of jQuery to events.
$(document).on('click', '.mainButton', function(){
//your code
})
You have two hrefs - one says javscript:void(); the other has a hash (#) Remove one. Then you won't get undefined.
You'll want to change data to data-id in your HTML. That way you can access the data properties in your javascript like so:
$('#btn-classified').on('click', function() {
alert($(this).data('id'));
});
$(this).data('data') would actually expect data-data="<?=$someId?>" in your HTML.
As per the docs https://api.jquery.com/data/ the attribute should be data-data
if it needs to be fetched through .data function.
$('document').ready(function()
{
$(document).on('click', '#btn-classified', function() {
//$("#btn-classified").on("click", function () {
//$("#btn-classified").click(function() {
var myvar1 = $(this).data('data');
alert(myvar1);
});
});
<script data-require="jquery" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<body>
<center>
<a href="#" class="btn-home" data-data="123" data-toggle="modal" data-target="#ApplyModal" name="btn-classified" id="btn-classified" >Apply
</a>
</center>
</body>
Use .attr('data') instead of .data('data') functions because .data function is used to Store arbitrary data associated with the matched elements or return the value at the named data store for the first element in the set of matched elements.

Capturing the anchor tag

I've written a JavaScript code which over-ride the native alert() method.
I need to capture the HTML element which comprises the code of alert() execution.
First two cases are examples. I have printed the elements in console.log.
Case 1 - Capturing the <script> tag:
HTML: <script> alert(1); </script>
JS:
window.alert = function()
{
console.log(document.currentScript); // <script> is printed
}
Case 2 - Capturing the <img> tag:
HTML: <img src='1' onerror="alert(1)">
JS:
window.alert = function()
{
console.log(arguments.callee.caller.arguments[0].target);
// arguments.callee --> console.log()
// arguments.callee.caller --> onerror(event) {}
// arguments.callee.caller.arguments[0] --> event
// arguments.callee.caller.arguments[0].target --> <img>
}
Case issue - Capturing the <a> tag:
HTML: Click here for alert
JS:
window.alert = function()
{
console.log( // how to find <a> element)
}
Please don't suggest me to modify the HTML by including IDs for <a> or something similar. Consider that the HTML is purely static, and I can't modify anything. I can just add a JavaScript, and I just wan't to know how this can be done.
You might be able to find such alerts and convert them to click events. Something like this. Note the click event alert call could be made much more sophisticated and potentially use eval(), but i leave that for you to risk.
window.alert = (function(){
var selected = document.querySelectorAll("a[href^='javascript:alert('");
Array.from(selected).forEach(function(item){
var old = item.href
item.addEventListener("click", function(){ alert(old.substring(11)); });
item.href="javascript:void(0);";
});
var _alert = function(msg) {
console.log(msg);
console.log(arguments.callee.caller.arguments[0].target);
};
return _alert;
})();
test
You can use load event at window; click event at selector "a[href='javascript:alert(1);']" to get value of href attribute; call event.preventDefault() within click handler; String.prototype.match() to create array of values withing href attribute; define matches globally; new Function(); Function.prototype.call() to set this to <a> element; call .click() on selector : <a> element with matched parameters returned by .match()
window.alert = function() {
console.log(arguments, this)
}
window.addEventListener("load", function() {
a = document.querySelector("a[href='javascript:alert(1);']");
a.addEventListener("click", function(event) {
event.preventDefault();
var data = this.href.replace(/javascript/, "");
matches = data.match(/\w+(?=\()|(\(.*\))/g);
matches[1] = matches[1].replace(/\(|\)/g, "");
var fn = new Function(matches[0] + ".call(a, matches[1])");
fn();
});
a.click();
});
Don't use the href attribute to call JavaScript. It should be avoided. It is not recommended usage. Use the onclick event instead. See here: https://stackoverflow.com/a/10242595/5969411
<script>
window.alert = function(msg, element) {
console.log('Msg:', msg);
console.log('Element:', element);
};
</script>
Test 1
Test 2
Test 3
I've returned false from the onclick event above in order to repress the anchor from going to '#' URL directive, but you could easily return true instead here, if you wish.

Pass value to function from <a> tag, not from button

Consider the following link and associated Javascript function:
<a class="someClass" href="#" onClick="someFunc('someVal'); return false;">Run someFunc</a>
function someFunc(val) {
doSomething(val);
}
I would prefer to refactor the link and Javascript function to support some additional functionality (the link is actually in a div returned by AJAX):
<a class="someClass" href="#" someAttribute="someVal">Run someFunc</a>
$(".someClass").click(function(e) {
e.preventDefault();
// How to get value of someAttribute?
doSomething(val);
});
How can I get the value of someAttribute? Thanks.
Use attr() method
$(".someClass").click(function(e) {
e.preventDefault();
// How to get value of someAttribute?
alert( $(this).attr('someAttribute'));
});
DEMO: http://jsfiddle.net/buC8k/
API refrence: http://api.jquery.com/attr/
The clicked element is this. You may use the attr function :
var someValue = $(this).attr('someAttribute');

Javascript: embedding a result of a function into a HREF

I have a javascript function that reformats a link. When a HREF link is clicked, I need to execute this method to finish creating the HREF.
Example JS method:
function fixURL (dest, val){
return dest + val;
}
I have an regular HREF and would like to combine the result of the above method to create:
<a href="http://www.site.com/" + fixURL('poo','no')>Click me!</a>
Is this possible and is it ideal to do so?
You can use an onclick handler. Note, you're generally better off not using inline event handlers like onclick="something...", so this is just for demonstration purposes.
Also, this will try to open a new window/tab with the search result.
<a target="_blank"
href="https://www.google.com/search?q=chris+rock"
rel="chris+rock|dave+chappelle"
onclick="fixURL(this)">Test</a>
function fixURL(el){
var vals = el.rel.split('|');
el.href = el.href.replace(vals[0],vals[1]);
}
http://jsfiddle.net/sxtuz/1/
The same effect, only using DOM event handlers. Note the id="fixme" attribute.
<a id="fixme"
target="_blank"
href="https://www.google.com/search?q=chris+rock"
rel="chris+rock|dave+chappelle">Test</a>
function fixURL(el){
var vals = el.rel.split('|');
el.href = el.href.replace(vals[0],vals[1]);
}
window.onload = function(){
document.getElementById('fixme').onclick = function(){
fixURL(this);
};
}
http://jsfiddle.net/sxtuz/
You can embed the result of a function into a href, yes, but the function call cannot be inlined within the HTML. Try this:
A link
<script type="text/javascript">
!function(links) {
links[links.length-1].href+=fixURL('arg1', 'arg2');
}(document.getElementsByTagName('a'));
</script>
If you keep it as:
Click Me!
You can then use jQuery to do:
$("a[href='http://www.site.com/']").attr("href", "http://www.site.com/" + fixURL('poo','no'))
Explanation:
The $("a[href='http://www.site.com/']") matches a element with an existing href equal to http://www.site.com/, then changes its href attribute to the second parameter that you pass in. In this case "http://www.site.com/" + fixURL('poo','no')

Categories

Resources