Assigning Click Event After Altering innerHTML - javascript

Using AngularJS w/ Meteor
Essentially, I have a ng-click event on a which calls a function that clones the and places it elsewhere. I changed some of the innerHTML so that there is a 'x' icon for removing the item. I would like to be able to click that new to remove it.
So, I know that setting an attribute of ng-click does not work. I am stuck on how I can make this happen.
my template addClass.html
<tr id="{{$index}}" ng-repeat="class in $ctrl.classes" ng-click="$ctrl.addThisClass($event)">
<td><span class="badge pull-left">{{class.units}}</span> {{class.name}}</td>
<td>{{class.number}}</td>
<td>{{class.teacher}}<span class="glyphicon glyphicon-plus text-danger pull-right"></span></td>
</tr>
the function it calls
addThisClass = function($event) {
var clone, table, tableBody, tableRow, tableRowLength, cmpTableData, tableData, tableDataText, remove, alert, footer;
clone = $event.currentTarget.cloneNode(true);
table = document.getElementById('queuedClasses');
tableBody = table.getElementsByTagName('tbody')[0];
tableRow = tableBody.getElementsByTagName('tr');
tableRowLength = tableBody.getElementsByTagName('tr').length;
tableData = clone.getElementsByTagName('td');
footer = document.getElementById("modalFooter");
tableDataText = tableData[2].textContent;
if (tableRowLength < 7) {
for (var i = 0; i < tableRowLength; i++) {
if (tableRow[i].getElementsByTagName('td')[1].textContent == tableData[1].textContent) {
if (footer.getElementsByClassName('alert').length === 0) {
alert = document.createElement('div');
alert.className = 'alert alert-danger text-left';
alert.id = 'alertMessage';
alert.setAttribute('role', 'alert');
alert.appendChild(document.createTextNode('Sorry, you already added that class to the queue.'));
footer.insertBefore(alert, footer.childNodes[0]);
setTimeout(function() {
$("#alertMessage").fadeTo(500, 0).slideUp(500, function() {
$(this).remove();
});
}, 3000);
}
return;
}
}
remove = '<span class="glyphicon glyphicon-remove text-danger pull-right" style="padding-top: 2px; !important;" title="Delete Class"></span>';
tableData[2].innerHTML = tableDataText + remove;
tableBody.appendChild(clone);
} else {
if (footer.getElementsByClassName('alert').length === 0) {
alert = document.createElement('div');
alert.className = 'alert alert-danger text-left';
alert.id = 'alertMessage';
alert.setAttribute('role', 'alert');
alert.appendChild(document.createTextNode('You cannot have more than 7 classes queued.'));
footer.insertBefore(alert, footer.childNodes[0]);
setTimeout(function() {
$("#alertMessage").fadeTo(500, 0).slideUp(500, function() {
$(this).remove();
});
}, 3000);
}
}
/* Reset Filter */
var input, filterTable, filterTR;
input = document.getElementById("searchForClasses");
input.value = '';
filterTable = document.getElementById("tableClasses");
filterTR = filterTable.getElementsByTagName("tr");
for (i = 0; i < filterTR.length; i++) {
filterTR[i].style.display = "";
}
}

Related

html not appending to the carousel on popover

I Am Trying to make a popover with a bootstrap carousel and where the carousel items are to be generated and appended from a script but I get the carousel but I am unable to append the item. I tried hard but I didn't come up with a solution.
the HTML initialized is as below
HTML:
<div class="popup" data-popup="popup-1">
<div class="popup-inner">
<i class="fas fa-bars"></i>
<div class="frame">
<div id='carousel' class='carousel slide' data-bs-ride='carousel'>
<div class='carousel-inner items-slider1'>
</div>
</div>
</div>
</div>
</div>
the script I have tried was
Javascript:
function findallchord(currentchord , currenttype) {
for (let i = 1; i < 10; i++) {
if (Raphael.chord.find(currentchord ,currenttype,i)) {
Raphael.chord("div3", Raphael.chord.find(currentchord , currenttype,i), currentchord +' ' +currenttype).element.setSize(75, 75);
}
}
}
var getChordRoots = function (input) {
if (input.length > 1 && (input.charAt(1) == "b" || input.charAt(1) == "#"))
return input.substr(0, 2);
else
return input.substr(0, 1);
};
$('.popup').on('shown.bs.popover', function () {
$('.carousel-inner').carousel();
});
$('[data-bs-toggle="popover"]').popover({
html: true,
content: function() {
return $('.popup').html();
}}).click(function() {
var oldChord = jQuery(this).text();
var currentchord = getChordRoots(oldChord);
var currenttype = oldChord.substr(currentchord.length);
findallchord(currentchord , currenttype);
var chordsiblings = $('#div3').children().siblings("svg");
for (let i = 1; i < 10; i++) {
if (Raphael.chord.find(currentchord , currenttype,i)) {
var itemid = "chord" + i;
var theDiv = "<div class='carousel-item"+((itemid=="chord1") ? ' active':'')+" ' id='"+currentchord+''+itemid+"'> "+chordsiblings[i-1].outerHTML+" </div>";
$('.items-slider1').append(theDiv);
}
}
});
I have also tried appendTo also as
$(theDiv).appendTo('.items-slider1');
Please Help to solve this
This is the output I get, the appended elements are not in the carousel
Note: I am using Bootstrap 5
Try instantiating the carousel after you've set it up
/*
$('.popup').on('shown.bs.popover', function () {
$('.carousel-inner').carousel();
});
*/
$('[data-bs-toggle="popover"]').popover({
html: true,
content: function() {
return $('.popup').html();
}}).click(function() {
var oldChord = jQuery(this).text();
var currentchord = getChordRoots(oldChord);
var currenttype = oldChord.substr(currentchord.length);
findallchord(currentchord , currenttype);
var chordsiblings = $('#div3').children().siblings("svg");
for (let i = 1; i < 10; i++) {
if (Raphael.chord.find(currentchord , currenttype,i)) {
var itemid = "chord" + i;
var theDiv = "<div class='carousel-item"+((itemid=="chord1") ? ' active':'')+" ' id='"+currentchord+''+itemid+"'> "+chordsiblings[i-1].outerHTML+" </div>";
$('.items-slider1').append(theDiv);
}
}
$('.carousel-inner').carousel();
});
It was needed to do call the click function first before popover as below
$('[data-bs-toggle="popover"]').click(function() {
var oldChord = jQuery(this).text();
var currentchord = getChordRoots(oldChord);
var currenttype = oldChord.substr(currentchord.length);
findallchord(currentchord , currenttype);
var chordsiblings = $('#div3').children().siblings("svg");
for (let i = 1; i < 10; i++) {
if (Raphael.chord.find(currentchord , currenttype,i)) {
var itemid = "chord" + i;
var theDiv = "<div class='carousel-item"+((itemid=="chord1") ? ' active':'')+" ' id='"+currentchord+''+itemid+"'> "+chordsiblings[i-1].outerHTML+" </div>";
$('.items-slider1').append(theDiv);
}
}
}).popover({
html: true,
content: function() {
return $('.popup').html();
}});

Stop taking input in text-field (tag input)

I am taking some tags name like "study","reading" something like that in the textfield with the help of Bootstrap 4 Tag Input Plugin With jQuery - Tagsinput.js and I have also some predefine tags name contain by buttons. If I click the button then the count of the tag's will increase (count++) and again click this button count will decrease(count--). Same rules for the text-field tags and the total count of the tags in both fields (text and buttons)<=5.
I can count the total tags of the both field but can't stop taking input in text-field when it is greater than 5.
html
<button class="btnr btnr-tags-optional" id="1" onclick="tagSelect(this.id)" >1</button>
<button class="btnr btnr-tags-optional" id="2" onclick="tagSelect(this.id)" >2</button>
<button class="btnr btnr-tags-optional" id="3" onclick="tagSelect(this.id)" >3</button>
My Js
var tagsCount = 0;
var store = 0;
var total_tags = 0;
function tagSelect(clicked_id) {
if (total_tags < 5) {
var tags = document.getElementById(clicked_id);
if (tags.style.borderColor == "rgb(255, 72, 20)") {
tags.style.borderColor = "";
tagsCount--;
} else if (tags.style.borderColor == "") {
tags.style.borderColor = 'rgb(255, 72, 20)';
tagsCount++;
}
total_tags = store + tagsCount;
}
console.log(total_tags);
}
$('#tags_text').on('change', function() {
if (total_tags >= 5) {
$("#tags_text").attr('readonly');
console.log('condition')
} else {
$("#tags_text").removeAttr('readonly');
var items = $("#tags_text").tagsinput('items').length;
store = items;
total_tags = store + tagsCount;
console.log(total_tags);
}
});
Here is the example in jsfiddle
This problem is solved.
I have changed the maxTags value of the plugin with the change of the tags click.
window.tagsCount = 0;
var store = 0;
var total_tags = 0;
function tagSelect(clicked_id) {
var r = ("#" + clicked_id).toString();
if (total_tags < 5) {
if ($(r).hasClass("classActiveIssue")) {
$(r).removeClass("classActiveIssue");
window.tagsCount--;
} else {
$(r).addClass("classActiveIssue");
window.tagsCount++;
}
} else {
if ($(r).hasClass("classActiveIssue")) {
$(r).removeClass("classActiveIssue");
window.tagsCount--;
}
}
total_tags = store + tagsCount;
$("#optionsleft").text(total_tags + "/5 selected");
//console.log("total",total_tags);
}
$('#tags_text').on('change', function() {
var items = $("#tags_text").tagsinput('items').length;
store = items;
total_tags = store + tagsCount;
});
and add the line in add:
self.options.maxTags = 5 - window.tagsCount;
Here is the fiddle

Javascript removes click handlers

I am new to javascript and I have written this javascript class to generate a table nested in an unordered list. I want to save the state on the table as on the main page I have multiple tabs and when I come back to the tab which displays this table it should have the same state as before. In my main script file I am creating an instance of this class and generating the custom table from the data only once during initialisation. I am calling the updateTable() method to add new data to the table every time this tab is opened, which adds new data to the ul and returns this.ul . I am able the save the state of the table but after the first time when I come back to this tab I am unable to trigger click events. Somehow the event handlers are not getting called after the 1st time.
import {TaskQueue} from './run-task-queue.js';
export class Table {
constructor(groups,file_dir, list_type) {
this.ul = $('<ul style="padding-top:10px;"></ul>');
this.data = groups;
this.type = list_type;
this.file_dir = file_dir;
this.selected = {};
this.runTaskQueue = new TaskQueue();
}
addTableHeader() {
var hdr = $('<li></li>');
var hdrDiv = $('<div class="row" style="margin:0;background-color:aliceblue"></div>');
var hdrCheckbox = $('<div class="my-auto" style="padding:10px"><input class="float-left" type="checkbox" style="cursor:pointer"></div>');
var hdrPlayIconDiv = $('<div class="my-auto float-right" style="padding:10px; flex:1; color:green;"></div>');
var hdrPlayIcon = $('<i class=" fa fa-play float-right" data-run-status="notrunning" style="cursor:pointer"></i>');
hdrPlayIcon.on('click',function(e){
status = e['target'].getAttribute("data-run-status");
if(status === 'running') {
e['target'].classList = ''
e['target'].classList = 'fa fa-play float-right';
e['target'].setAttribute("data-run-status", "notrunning");
this.runTaskQueue.clearTaskQueue();
}
else {
e['target'].classList = ''
e['target'].classList = 'fa fa-pause float-right';
e['target'].setAttribute("data-run-status", "running");
this.runTaskQueue.enqueueTaskList(this.selected);
}
}.bind(this));
hdr.css('cursor','default');
hdrDiv.append(hdrCheckbox);
hdrPlayIconDiv.append(hdrPlayIcon);
hdrDiv.append(hdrPlayIconDiv);
hdr.append(hdrDiv)
this.ul.append(hdr);
}
generateTableRow(val) {
var row = $('<tr></tr>');
var cell = $('<td></td>').text(val);
if(this.type === 'test') {
var checkboxCell = $('<td></td>');
var checkbox = $('<input type="checkbox">');
checkbox.on('click', function(e){
if(!e.target.checked)
delete this.selected[val]
else {
var task = {};
task['file_name'] = val;
task['file_dir'] = this.file_dir;
var x = ($(e.target).parent().siblings()[2]);
task['element'] = x.children[0].children[0];
task['doneClassList'] = "fa fa-play float-right";
task['queueClassList'] = "fa fab fa-stack-overflow float-right",
task['runningClassList'] = "fa fa-spinner fa-spin float-right",
this.selected[val] = task;
}
console.log(this.selected)
}.bind(this));
checkboxCell.append(checkbox);
row.append(checkboxCell);
}
row.append(cell);
if(this.type ==='replay' || this.type ==='test') {
var editIcon = $('<td style="flex:1;"><div class="my-auto float-right" style="padding:10px; color:#15AABF;"><i class=" fa fa-edit float-right"></i></div></td>');
row.append(editIcon);
}
if(this.type === 'test') {
var playIcon = $('<td style="flex:1;"><div class="my-auto float-right" style="padding:10px; color:green;"><i class="fa fa-play float-right"></i></div></td>');
playIcon.on('click', function(e){
console.log(e);
console.log(this);
var element = e['target'];
// element.classList.remove("fa-play");
// element.classList.add('fa-spinner');
// element.classList.add('fa-spin');
this.runTaskQueue.enqueueTask({'file_name': val,'file_dir': this.file_dir, 'element':e.target,
'queueClassList' : "fa fab fa-stack-overflow float-right",
'runningClassList': "fa fa-spinner fa-spin float-right",
'doneClassList':"fa fa-play float-right"});
//e['target'].classList.remove('color','blue');
}.bind(this))
row.append(playIcon);
}
return row;
}
generateTableListItem(key) {
var li = $('<li class="hide_group"></li>');
var div = $('<div class="row" style="margin:0;"></div>');
var p = $('<div class="my-auto" style="padding:10px;flex:1"></div>').append($('<p class="my-auto"></p>').text(key));
var i = $('<div class="my-auto float-right" style="padding:10px" ><i class=" fa fa-plus float-right"></i></div>');
p.on('click',function(){
$(this).parent().parent().toggleClass('hide_group');
});
i.on('click',function(){
$(this).parent().parent().toggleClass('hide_group');
})
var nestedTable = $('<table class="tabel table-hover" style="width:98%; margin-left:20px;"></table>');
this.data[key].forEach(val => {
var row = this.generateTableRow(val);
nestedTable.append(row);
})
if(this.type === 'test'){
var checkbox = $(`<div class="my-auto" style="padding:10px"><input class="float-left" type="checkbox" ></div>`);
checkbox.on('click', function(){
console.log('checkbox -clicked')
});
div.append(checkbox);
}
div.append(p);
div.append(i);
li.append(div);
li.append(nestedTable);
return li;
}
generateTableFromGroups() {
this.ul.empty();
if(this.type === 'test')
this.addTableHeader();
Object.keys(this.data).forEach(key => {
var li = this.generateTableListItem(key);
this.ul.append(li);
})
console.log('this.ul');
console.log(this.ul);
return this.ul;
}
updateTable(data) {
var currentData = this.data;
var currentKeys = Object.keys(currentData);
var newData = data;
var newKeys = Object.keys(newData);
var deltaPositive = newKeys.filter(x => !currentKeys.includes(x));
deltaPositive.forEach(key => {
this.data[key] = newData[key];
this.generateTableListItem(key);
});
console.log('this.ul');
console.log(this.ul);
return this.ul;
}
}
Parts of the main script file, the init() function gets the initial data and initialises the tables. $.fn.show_files_list is attached to a button and is responsible for updating the table and displaying it. The table is being displayed when I click this button, but inside the table I have some buttons that should trigger some events. When I come to this tab for the first time all the buttons in the generated table work fine but if I leave this tab and come back to this tab the buttons in the table stop working.
import {Table} from './table-module.js';
$(document).ready(function(){
var testTable;
var replayTable;
const get_file_list = (url) => {
var dfd = jQuery.Deferred();
fetch(url)
.then((resp) => (resp.ok) ?resp.json() : new Error('something went wrong'))
.then(function(data) {
dfd.resolve(data);
})
.catch(err => {
console.log(err);
dfd.reject(err);
})
return dfd.promise();
}
$.fn.show_files_list = function(key1, key2, table) {
$(this).siblings().removeClass('btn-info');
$(this).siblings().addClass('btn-outline-info');
$(this).removeClass('btn-outline-info');
$(this).addClass('btn-info');
get_file_list('/get_file_list')
.done( (all_files) => {
var dir = all_files[key1];
var files = all_files[key2];
var groups = group_files(files);
console.log('Display Table');
var genTable = table.updateTable(groups);
$('#display_files').empty();
$('#display_files').append(genTable);
})
.fail(function(err) {
console.log(err);
});
}
const init = () => {
get_file_list('/get_file_list')
.done( (all_files) => {
var test_dir = all_files['test_dir'];
var test_files = all_files['test_files'];
var test_groups = group_files(test_files);
testTable = new Table(test_groups, test_dir, 'test');
testTable.generateTableFromGroups();
var replay_dir = all_files['repaly_dir'];
var replay_files = all_files['replay_files'];
var replay_groups = group_files(replay_files);
replayTable = new Table(replay_groups, replay_dir, 'replays');
replayTable.generateTableFromGroups();
$.fn.show_logs('aut');
})
.fail((err) => {
console.log(err);
})
}
init();
}
It would be a great help if someone could point me in the right direction.
Edit:
If I use vanilla js to attach event handlers to the elements it works.
With Jquery's on method I am seeing the above mentioned error. See below for the vanilla js event handler that works.
hdrPlayIcon[0].addEventListener('click',function(e){
status = e['target'].getAttribute("data-run-status");
if(status === 'running') {
e['target'].classList = ''
e['target'].classList = 'fa fa-play float-right';
e['target'].setAttribute("data-run-status", "notrunning");
this.runTaskQueue.clearTaskQueue();
}
else {
e['target'].classList = ''
e['target'].classList = 'fa fa-pause float-right';
e['target'].setAttribute("data-run-status", "running");
this.runTaskQueue.enqueueTaskList(this.selected);
}
}.bind(this));
Why is the Jquery's on function not working?
Just use the below method for remove the click listener
document.getElementById("myDIV").removeEventListener("click", myFunction);

how to change the css of the parent div in javascript not jquery

I want to change the CSS of a parent div if I click the child of its parent div, not, for example if I click href tag. I want to change the CSS of its class="changed_area".
How can I do this?
var up_btn = document.getElementsByClassName('up_btn');
var up_btn_length = up_btn.length;
var changed_area = document.getElementsByClassName('changed_area');
var changed_area_length = changed_area.length;
for (var i = 0; i < up_btn_length; i++) {
up_btn[i].addEventListener('click', function() {
//alert('welcome');
for (var i = 0; i < changed_area_length; i++) {
if (changed_area[i].style.top == '-100%') {
changed_area[i].style.top = '0%';
}
else {
changed_area[i].style.top = '-100%';
}
}
});
}
<?php foreach($questions As $question): ?>
<div class="changed_area" style="width: 100px;">
<div class="inside_ajax_part1">
<div id="inside_left">
<img src="<?php echo $Filter_customer->image; ?>" />
</div>
<div id="inside_right">
<a class="up_btn" href="#">Up</a>
</div>
</div>
<div class="inside_ajax_part2">
<p>mohammed</p>
</div>
</div>
<?php endforeach; ?>
I think you can do something like this : https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
EDIT : better way to do this
for (var i = 0; i < up_btn_length; i++) {
up_btn[i].addEventListener('click', function(){
var changed_area = up_btn[i].parentElement;
if ( changed_area.classList.contains('changed_area') ) {
changed_area.classList.remove('changed_area')
}
else {
changed_area.classList.add('changed_area')
}
if(changed_area.style.top == '-100%') {
changed_area.style.top = '0%';
}
else {
changed_area.style.top = '-100%';
}
});
}
Just add event listener on parent and use currentTarget
const parent = document.getElementsByClassName('changed_area');// select parent
for (var i = 0; i < parent.length; i++) {
parent[i].addEventListener('click', (ev) => ev.currentTarget.className = 'clicked');
}
Here is fiddle for it
Your code affects all of your divs with class "changed_area", That I don't think it is what you intend.
To access a parent element with javascript you can use parentElement. To get the parent of parent of parent.... that meets some condition (like having a class) you can do this:
function Get_changed_area(targetElement){
var parent = targetElement.parentElement;
if(parent.hasClass('changed_area'))
return parent;
else Get_changed_area(parent) //repeat the function for parent
}
for (var i = 0; i < up_btn_length; i++) {
up_btn[i].addEventListener('click', function() {
changed_area = Get_changed_area(up_btn[i]);
if (changed_area.style.top == '-100%') {
changed_area.style.top = '0%';
}
else {
changed_area.style.top = '-100%';
}
}
}

How can put an id text in a text box by click on it?

I want that when I click on id it sends my value in id=arxidia and when I click again on mounoxilo it removes it.
<div class="poutsa" id="mounoxilo1" value="vizia1">etsi1</div>
<div class="poutsa" id="mounoxilo2" value="vizia2">etsi2</div>
<div class="poutsa" id="mounoxilo3" value="vizia3">etsi3</div>
<div class="poutsa" id="mounoxilo4" value="vizia4">etsi4</div>
<input type="text" id="arxidia">
using jquery
jQuery("#mounoxilo").click(function(){
if(jQuery("#arxidia").val() == "") {
jQuery("#arxidia").val(jQuery("#mounoxilo").attr("value"));
} else {
jQuery("#arxidia").val("");
}
}
Not using jQuery:
document.getElementById('mounoxilo').onclick = function(e) {
var inputEl = document.getElementById('arxidia');
if(inputEl.value) {
inputEl.value = "";
} else {
inputEl.value = this.getAttribute('value');
}
}
EDIT 1
JSFiddle: http://jsfiddle.net/XwAY5/
For the edited question it's like this:
var divEls = document.getElementsByClassName('poutsa');
for(var i = 0; i < divEls.length; i++) {
divEl = divEls[i];
divEl.onclick = function(e) {
var inputEl = document.getElementById('arxidia');
if(inputEl.value == this.getAttribute('value')) {
inputEl.value = "";
} else {
inputEl.value = this.getAttribute('value');
}
}
}
JSFiddle: http://jsfiddle.net/XwAY5/2/
EDIT 2
Appearently, the input should be able to hold multiple values, so I came up with this: http://jsfiddle.net/XwAY5/3/

Categories

Resources