Hyperlink's click function is not available after rendered - javascript

I do some string manipulations and wanna create a string like below. [sample] and [express] are hyperlinks.
<a> element should have click function and it should call searchFromURL().
But once it is rendered, the click function is not available, what might be the reason behind that?
Or is there any other way to accomplish this?
home.page.html
<ion-row innerHTML="{{buildNavigationSearchElement(dicDat.translation)}}"></ion-row>
home.page.ts
buildNavigationSearchElement(elementText: String){
let retElem = elementText + 'Search Text';
return retElem;
}
Is there a safest way to build this element with click function?

Finally I came up with this solution. As follows the hyperlink is generated.
home.page.html
<div [innerHTML]="buildNavigationSearchElement()"></div>
home.page.ts
buildNavigationSearchElement(){
let myText = This is a + '<a class="myhyperlink_1">sample</a>' + text to + '<a class="myhyperlink_2">express</a>' + my issue.
return myText;
}
Inside ngAfterViewChecked() event each and every hyperlink is bound to a class method.
ngAfterViewChecked() {
var myElements =
this.elementRef.nativeElement.querySelectorAll('[class^="myhyperlink"]');
var i: number;
for (i = 0; i < myElements.length; i++) {
myElements[i].addEventListener('click', this.openAlert.bind(this));
}
}
Property array is stored in class with actions and parameters for each hyperlinks.
openAlert(parameter: any) {
let className = parameter.srcElement.className;
//do what ever required
}

Related

Why my Chrome extension event doesn't work?

I'm trying to create a chrome extension. I had a problem with the affectation of event for the new element that i append to the dom of site with content. Js
If I add an event to an element' 'for example class' exist already in the page, it works correctly. Just for my new appended element((in the code iadded a button ,the event is just an alert to test))
function tst() {
myclass = $("._3hg-._42ft");
myclass = myclass.not(".supp");
myclass.addClass("supp");
var patt = /https:\/\/(.)*\.facebook\.com\/(.)*\/(posts|photos|videos)\/(\w|\.|\d)*/g;
for (i = 0; i < myclass.length; i++) {
result = patt.exec(myclass[i]);
myclass.append('<button class="fact" id=' + result[0] + ' style="position: absolute;">fact</button>');
};
/* this is a simple event*/
/***********************/
$(".fact").on('click', function() {
alert("no event work ");
});
Making somewhat broad assumption here in my answer that it is JavaScript/jQuery related and is NOT an extension...or is so still in that context.
You need to attach the event to the container here perhaps for the dynamically created elements. Lots of global stuff, suggested to not do that, updated there.
Appends a lot of buttons perhaps? might need to only hit DOM once but left as-is in this isolated function.
function tst() {
let myclass = $("._3hg-._42ft")
.not(".supp");
myclass.addClass("supp");
//let result = {};
var patt = /https:\/\/(.)*\.facebook\.com\/(.)*\/(posts|photos|videos)\/(\w|\.|\d)*/g;
var i = 0; //avoid global
for (i; i < myclass.length; i++) {
// broad assumption of the returned value from patt.exec() here
// not even sure why it needs an id, have a class, use for css
let result = patt.exec(myclass[i]);
myclass.append('<button class="fact" id="' + result[0] + '">fact</button>');
}
/* attache event to pre-existing element */
/***********************/
myclass.on('click', ".fact", function() {
alert("event works");
});
}
button.fact {
position: absolute;
}

How to instantiate buttons in a HTML table, whose role is to call a JS function in the scope

I'd like to pass a function as parameter in JavaScript,
that function is a reference onto a function stored globally
alertHello = function() {
alert("Hello")
}
for instance, I'd like to create a table from JSON array, which has an actions embedded array.
So I'd like to pass each function stored in actions attribute in my JSON object like this :
{
...
actions : [
{func : alertHello, icon : myIcon}
]
}
So when I create the table, I add a column based on the actions attributes :
for(var i = 0; i < actions.length ; i++)
{
body += "<button class='ui primary icon button' onclick="+actions[i].func+"><i class='"+actions[i].icon+" icon'></i></button>";
}
But I got a "function statement requires a name" error
Actually, I figured out that a 'wrapping function' was what I was looking for,
and I needed to pass the function name as String in the wrapping function this way :
var actions = [ { func : 'sayHello', icon : 'edit' }]
I created a simple wrapping function (notice that this works only on client side) :
wrapFunc = function(func)
{
var fn = window[func];
fn();
}
And then when I've to build the table :
body += "... onclick=wrapFunc('"+actions[i].func+"')><i class='"+actions[i].icon+" icon'></i></button>";
Finally, when the page is loaded, the function will only be triggered once I'll click the specific button.
I hope this could help other folks. By the way, my question was not completely relevant.
I see no definition for body, nor do I think += will work. Additionally, the function should not be wrapped in quotes or with pluses. Try this:
var body = document.getElementsByTagName('body')[0]
for(var i = 0; i < actions.length ; i++) {
var btn = document.createElement('button');
btn.className = 'ui primary icon button';
btn.onclick = actions[i].func();
var i = document.createElement('i');
btn.appendChild(i);
i.className = actions[i].icon;
}
You may also need to add var to your alertHello definition, like this:
var alertHello = function() {
alert("Hello")
}
Here's a fiddle: https://jsfiddle.net/17ex1ksr/1/
for(var i = 0; i < actions.length ; i++)
{
body += "<button class='ui primary icon button' onclick="+actions[i].func+"()><i class="+actions[i].icon+" icon></i></button>";
}
This should work since actions is a global array, however your quotation marks seem to be out of place. So, inside your loop, instead of
<... onclick="+actions[i].func+" ...>
do
<... onclick='actions[" + i + "].func()' ...>`
This will render:
<button onclick='actions[0].func()'> ...
<button onclick='actions[1].func()'> ...
<button onclick='actions[2].func()'> ...
Example: Function as OnClick Parameter.

Javascript onclick parameter

I have a question about "onclick" function in JavaScript. Here I have a div "InfoBar"
<div id="InfoBar"><br>
and two for loop
var src = new Array();
for(var i = 0; i < 2; i++){
src.push("el1","el2");
}
for(var j = 0; j < 2; j++){
doesFileExist(src[j]);
}
and a doesFileExist() and klick function
function klick(el){
alert(el)
}
function doesFileExist(urlToFile){
document.getElementById('InfoBar').innerHTML += '<br>' + '<a id="css" onclick="klick(urlToFile)" href="#" title="'+urlToFile+'">' + "link1 : " + urlToFile + '</a>';
}
now I've added a "onclick" function in "a href".
if I click on "link1:el1", I want to display as alert "urlToFile" string.
But I doesn't work.
In "a href" title="'+urlToFile+'" it works perfect, but in "onclick" doesn't work.
Can anyone help me?
Thanks in advance.
You are generating an attribute. That gets converted back into a function but the scope is broken.
Don't use intrinsic event attributes.
Minimise use of globals
Avoid generating HTML by mashing strings together (at best it is hard to read, at worst you get this sort of issue)
Use standard DOM:
var container = document.getElementById('InfoBar');
container.innerHTML = ""; // Delete any existing content
container.appendChild(document.createElement('br'));
var anchor = document.createElement('a');
anchor.setAttribute('id', 'css'); // You are running this function is a loop and creating duplicate ids. Use a class instead.
anchor.addEventListener('click', function (event) {
klick(urlToFile); // the local variable urlToFile is still in scope
});
anchor.setAttribute('href', '#'); // Why are you linking to the top of the page? Use a <button>
anchor.setAttribute('title', urlToFile);
anchor.appendChild(document.createTextNode("link1 : " + urToFile));
container.appendChild(anchor);
Event handles assigned this way won't work. You have to use JavaScript event handles. Means, you must create a new 'a' element, then bind a click event to it, and then append it as a child to the parent node. All this stuff is very good described on the web out there.

Using this within functions called with onclick event in Javascript

I'm currently building a small Todo list application using vanilla Javascript but I'm having some issues creating a delete button that onClick removes it's parent element.
From what I have read, when an onClick is called in Javascript the this keyword can be used to refer to the element that called the function. With this in mind I have the following code:
window.onload = initialiseTodo;
function addRecord(){
var title = document.getElementById('issueTitle');
var issueContent = document.getElementById('issueContent');
var contentArea = document.getElementById('contentArea');
if(title.value.length > 0 && issueContent.value.length > 0){
var newItem = document.createElement('div');
newItem.id = 'task' + count++;
newItem.className = 'task';
newItem.innerHTML = '<div class="taskbody"><h1>' + title.value + '</h1>'+ issueContent.value + '</div><div class="deleteContainer">'
+ '<a class="delete">DELETE</a></div>';
contentArea.appendChild(newItem);
assignDeleteOnclick();
}
}
function deleteRecord(){
this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
}
function assignDeleteOnclick(){
var deleteArray = document.getElementsByClassName('delete');
for(var i=0;i<deleteArray.length;i++){
deleteArray[i].onclick= deleteRecord();
}
}
function initialiseTodo(){
var btn_addRecord = document.getElementById('addRecord');
btn_addRecord.onclick = addRecord;
}
Basically I have a form that has two fields. When these fields are filled and the addRecord button is clicked a new div is added at the bottom of the page. This div contains a delete button. After the creation of this I assign an onclick event to the delete button which assigns the deleteRecord function when the delete button is clicked. My issue is with the deleteRecord function. I have used this to refer to the calling element (the delete button) and wish to remove the task div that is the outermost container however I current get a message that says: 'Cannot read property 'parentNode' of undefined ' which suggests to me the this keyword is not working correctly.
Any help would be greatly appreciated.
I've added the full code to a fiddle.
http://jsfiddle.net/jezzipin/Bd8AR/
J
You need to provide the element itself as a parameter. I did so by changing the html to include onclick="deleteRecord(this)" to make it a little easier to deal with. This means you can remove the assignDeleteOnclick() function
function deleteRecord(elem){
elem.parentNode.parentNode.remove();
}
Demo
You might style the .content to be hidden better if there are no elements to prevent that extra white space
Edit
Since you don't want an inline onclick, you can do it with js the same:
function deleteRecord(elem){
elem.parentNode.parentNode.remove();
}
function assignDeleteOnclick(){
var deleteArray = document.getElementsByClassName('delete');
for(var i=0;i<deleteArray.length;i++){
// Has to be enveloped in a function() { } or else context is lost
deleteArray[i].onclick=function() { deleteRecord(this); }
}
}
Demo

Javascript Weird - I'm clueless

I'm working on this menu-system that's very similar to how operating systems do them.
Using jquery etc.
I have 2 comments down in the For Loop. It's basically outputting the last index each in the $(document).on('click')... function. But outside the document.on it works fine.
It's probably just an obvious problem but I've spent about an hour on this.. Thanks in advance!
menu: function(title) {
this.title = title;
this.slug = slugify(title);
this.icon = false;
this.buttons = Object();
this.num_buttons = 0;
this.visible = false;
this.timeout_id = null;
this.is_hovering_dropdown = false;
this.is_hovering_menu = false;
this.render = function() {
var that = this;
var slug = that.slug;
var str = '<li id="menu-' +slug +'">' + this.title + '';
if (this.num_buttons > 0) {
str += '<ul id="menu-dropdown-' + slug + '" style="display: none;" class="dropdown">';
for (var button in this.buttons) {
str += '<li>' +that.buttons[button]['title'] +'</li>'
alert(button) //new project, open project, save as etc.
$(document).on("click", "#menu-dropdown-" +slug + '-' + that.buttons[button]['slug'], function() {
$("#menu-dropdown-" + slug).hide("fade", 200);
that.visible = false;
alert(button);//save as, save as, save as, save as etc.
});
}
}
}
}
Here you go:
Thanks to the order of operations, and scoping, all of your buttons are being saved with a reference to the LAST value of button.
What you want to do is put that assignment inside of an immediately-invoking function, and pass the button into that particular function-scope.
(function (button) { $(document). //...... }(button));
Everything inside of the immediate function should still have access to the static stuff outside of the immediate-function's scope (ie: that), AND it will also have a reference to the current value of button, as it's being invoked then and there.
The longer version of the story is that your buttons, when being created are being given a reference to button, rather than the value of button, therefore, when they're actually invoked at a later time, they reference the value of button as it currently exists (ie: the last value it was assigned in the loop).

Categories