Bootstrap 4 popover added dynamically cannot dismiss - javascript

I have Bootstrap 4 popovers added dynamically to a table.
I initialize my popover like this:
// Initialize popover
$('body').popover({
html: true,
template:
'<div class="popover popover-row-field" role="tooltip">' +
'<div class="arrow"></div>' +
'<button type="button" class="btn-popover-header btn-edit-popover-close float-right text-primary" aria-label="Close">' +
'<i class="fal fa-check"></i>' +
'</button>' +
'<button type="button" data-action="undo" class="btn-popover-header action-button text-primary float-right">' +
'<i class="fal fa-undo"></i>' +
'</button>' +
'<h3 class="popover-header"></h3>' +
'<div class="popover-body"></div>' +
'</div>',
placement: 'bottom',
trigger:'click',
position: 'relative',
selector: '.btn-edit-cell',
});
I have an event listener for a close button on the popover:
// Close popover by clicking the X
$(document).on('click', '.btn-edit-popover-close', function() {
$('.btn-edit-cell').popover('hide').popover();
});
I then clone a template row and add it to the table:
<td class="field-editor-input align-top">
<button type="button" class="btn-popover-header text-light btn-edit-cell save-btn-group" data-link="{{ $col->header }}-new"
data-html="true" title="{{ pretty_heading($col->header) }}" data-row-id="#row-template-new"
data-content="<textarea id='text-{{ $col->header }}-new' name='{{ $col->header }}' class='form-control popover-edit-field'></textarea>">
<i class="fal fa-pen text-light"> </i>
</button>
<div id="div-{{ $col->header }}-new" data-orig=""></div>
</td>
The popover opens OK but the close button does not fire.
Additionally, the popover does not stay fixed to its target if I scroll the page.
Thanks

Related

How to hide the parents of several elements with the same class?

I am trying to use .hide() from jQuery to hide some the parents of the li's that has the same class. No success so far. I see the other things like .addClass works fine, but .hide() is not working on this one?
Can someone give me a hand?
This is my code:
add()
function add() {
var element = document.getElementById("tasks");
var name = "acb"
$(element).append(
'<div class="d-flex mt-4">' +
'<span class="col-1">' +
'<li class="not-done" onclick="done(this)">' + name + '</li>' +
'</span>' +
'<span class="col-3">' +
'<button type="button" class="btn-edit">Edit</button>' +
'</span>' +
'</div>'
)
}
$("#show-done").click(function() {
$("li.not-done").parent().parent().hide();
// $("li.done").show();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="tasks">
<div class="d-flex mt-4">
<span class="col-1">
<li class="done" onclick="done(this)">xys</li>
</span>
<span class="col-3">
<button type="button" class="btn-edit">Edit</button>
</span>
</div>
</div>
<button id="show-done">show</button>

Button that open a Modal don't execute my function

I have this button for opening a modal box and I whould like to execute a function of the pressed button at the same time opening the modal. The modal is opening but the function no.
Here is my code
$.each(data, function (i, item) {
$('#fileListTable tbody').append("<tr><td>" + item.File + "</td><td>" + item.DateUpload + "</td><td>" + `
<i class="fa fa-file-pdf-o" aria-hidden="true"></i> PDF
<i class="fa fa-file-pdf-o" aria-hidden="true"></i> Quest
` + "</td > <td>" + `
<button id="btnStatus`+ i +`" class="btn btn-primary btn-xs btn-status" data-toggle="modal" href="#static"><i class="fa fa-list-alt" aria-hidden="true"></i> Status</button>
` + "</td><td id='statusContainer"+ i +"'>" + item.Status + "</td><td>" + item.Comments + "</td></tr > ");
});
my function
$('button[id^="btnStatus"]').click(function () {
console.log('A button was clicked');
});
You have dynamic element. So you need to attach click using on event
$('body').on('click', 'button[id^="btnStatus"]', function() {
console.log('A button was clicked');
});

Problems with wrong positioning elements

I'm creating a simple WordPress functionality, where users can add texts and edit some content:
When i decrease the width to 5/12 it looks like this:
Which is bad and not correctly positioned. Also, the pencil is not clickable and cannot use his functionality. Not sure if it's JavaScript/jQuery problem, or some CSS styles are broken. I'm creating the elements in the following way:
$(".row-container .dx-columns-wrapper").droppable({
accept: '.top-wrapper .dx-draggable-row, .top-wrapper .dx-draggable, .dx-columns, .dx-droppable',
tolerance: "touch",
activeClass: "dx-ui-state-highlight",
drop: function(event, ui) {
var element_class = $(ui.helper[0]).attr('class').split(' ')[0];
if (element_class == 'dx-draggable-row') {
var rows_id = 0;
$('.dx-droppable').each(function() {
var checked = $(this).data('row');
if (parseInt(checked) > parseInt(rows_id)) rows_id = checked;
});
rows_id++;
$(this).append('<div class="dx-droppable" data-row="' + rows_id + '">' +
'<div class="dx-droppable-header">' +
'<i class="fa fa-arrows-alt js-move-row" title="Move Row"></i>' +
'<span class="pull-left dx-row-title">Row ' + rows_id + '</span>' +
'<i class="fa fa-close pull-right dx-remove-row js-remove-row" title="Remove Element"></i>' +
/** Edit row class */
'<button class="js-edit-row-classes-btn-ok dx-edit-row-classes-btn-ok pull-right">OK</button>' +
'<i class="js-edit-row-classes-btn dx-edit-row-classes-btn fa fa-pencil pull-right" title="Edit Classes"></i>' +
'<span class="dx-row-classes pull-right">Row Classes</span>' +
'<input type="text" class="dx-row-class-input">' +
'</div><br></div>');
$(document).init_comp();
} else {
var data_type = $(ui.helper[0]).data('type');
var content = $(ui.helper[0]).html();
if (data_type != undefined) {
var col_id = 0;
$('.dx-columns').each(function() {
var check = $(this).attr('data-indx');
if (parseInt(check) > parseInt(col_id)) col_id = check;
});
col_id++;
$(this).append(
'<div class="dx-columns dx-col-12" data-view="' + data_type + '" data-indx="' + col_id + '">' +
'<i class="fa fa-arrows-alt dx-move-column js-move-column" title="Move Element"></i>' +
'<span class="dx-section-name">' + content + '</span>' +
'<i class="fa fa-arrow-left js-decrease-column-width" title="Decrease Element Width"></i>' +
'<span class="dx-column-part">12</span>' +
'<span>/</span>' +
'<span class="dx-column-full">12</span>' +
'<i class="fa fa-arrow-right js-increase-column-width" title="Increase Element Width"></i>' +
'<i class="fa fa-close pull-right dx-remove-column js-remove-column" title="Remove Element"></i>' +
'<i class="fa fa-cog pull-right dx-setting-column js-setting-column" title="Element Setting"></i>' +
'<i class="fa fa-copy pull-right js-copy-column" title="Copy Element"></i>' +
'<i class="fa fa-align-justify pull-right"><span class="small-column-properties"><i class="js-edit-col-classes-btn fa fa-pencil" title="Edit Classes"></i><i class="fa fa-copy js-copy-column" title="Copy Element"></i><i class="fa fa-cog dx-setting-column js-setting-column" title="Element Setting"></i><i class="fa fa-close dx-remove-column js-remove-column" title="Remove Element"></i></span><div id="triangle-down"></div></i>' +
'<button class="js-edit-col-classes-btn-ok dx-edit-col-classes-btn-ok pull-right">OK</button><i class="js-edit-col-classes-btn fa fa-pencil pull-right" title="Edit Classes"></i><span class="dx-col-classes pull-right">Column Classes</span>' +
'</div>'
);
$(document).find(".dx-columns").draggable({
helper: 'clone',
cursor: 'move',
handle: '.js-move-column'
});
} else {
$(ui.draggable).appendTo(this);
}
}
}
});
Any ideas how it's possible to prevent this issue ?

Add dynamic element onClick and make link disable then removing it with link clickable again

I want to add an dynamic input element onClick with jQuery and make the link disable. On deleting the input element that I just added I want to make the link clickable again.
I did the first part of adding element and making the link disable but the problem is when I add multiple elements and try to delete only one element all other links become clickable. I know, because I have given class to dropdown links. Not sure what to do to get this working right.
Here is my code:
$(document).ready(function() {
$(".list").on('click', function() {
$("#blockFeild").append(
'<div class="row parent">' +
'<div class="col-md-8">' +
'<input class="form-control" type="text">' +
'</div>' +
'<button class="btn btn-info" id="editbtn"><i class="fa fa-pencil" aria-hidden="true"></i></button>' +
'<button class="btn btn-danger" id="removebtn"><i class="fa fa-trash-o" aria-hidden="true"></i></button>' +
'<br><br>' +
'</div>'
).show();
});
});
$(document).on('click', 'a.list ', function() {
$(this).addClass('no-click');
});
$(document).on('click', 'li.block', function() {
$(this).addClass('not-allowed');
});
$(document).on("click", "#removebtn", function() {
$(this).closest('.parent').remove();
$(".block").removeClass("not-allowed");
$(".list").removeClass("no-click");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Add Block
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<?php $users_fields=$ this->db->list_fields('users'); for ($i=0; $i
<count($users_fields); $i++){ ?>
<li class="block">
<a class="list" href="#">
<?php echo $users_fields[$i]?>
</a>
</li>
<?php } ?>
</ul>
</div>
Your problem stems from duplicate ids (#removebtn, remember ids must be unique) and also this section of your code:
$(".block").removeClass("not-allowed");
$(".list").removeClass("no-click");
These two lines grab all elements on the page with the classes "not-allowed", and "no-click" respectively and then remove those classes. This is why the removal of one of your rows enables all your dropdown links again.
You need to create a way to associate a generated row with ONLY the link used to generate it, perhaps through the addition of an identifying class on both the row and link. That way when the row is destroyed you can use jQuery to grab that specific link element and re-activate it.
UPDATE
Now that I understand the OP better I updated this Snippet with .index() and .eq() in order to associate the correct .block .list with a matched .removebtn. Also replaced .remove() with .hide(). Works perfect.
Change all ids to classes. ex. from #removebtn to .removebtn. You can only have unique ids. When elements are generated, they have the same id, so that's why they are all affected. I don't quite fully understand OP's objective, but I bet having duplicate ids is the root of the problem.
In order to remove a .parent.row on it's own .removebtn replace the last 4 lines with these lines:
$('.list').on('click', function() {
$(this).addClass('no-click');
});
$('.block').on('click', function() {
$(this).addClass('not-allowed');
});
$(document).on("click", '.removebtn', function(e) {
var tgt = $(this);
idx = tgt.closest('.row').index()
$('.block').eq(idx).removeClass('not-allowed').find('.list').removeClass('no-click');
tgt.closest('.row').hide();
});
SNIPPET
$(document).ready(function() {
$(".list").on('click', function() {
$(".blockfield").append(
'<div class="row parent">' +
'<div class="col-md-8">' +
'<input class="form-control" type="text">' +
'<button class="btn btn-info editbtn"><i class="fa fa-pencil" aria-hidden="true"></i></button>' +
'<button class="btn btn-danger removebtn"><i class="fa fa-trash-o" aria-hidden="true"></i></button>' +
'<br><br>' +
'</div>' +
'</div>'
).show();
});
});
$('.list').on('click', function() {
$(this).addClass('no-click');
});
$('.block').on('click', function() {
$(this).addClass('not-allowed');
});
$(document).on("click", '.removebtn', function(e) {
var tgt = $(this);
idx = tgt.closest('.row').index()
$('.block').eq(idx).removeClass('not-allowed').find('.list').removeClass('no-click');
tgt.closest('.row').hide();
});
.no-click {
pointer-events: none;
}
.not-allowed {
cursor: not-allowed;
}
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Add Block
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li class="block">
<a class="list" href="#">1</a>
</li>
<li class="block">
<a class="list" href="#">2</a>
</li>
<li class="block">
<a class="list" href="#">3</a>
</li>
</ul>
</div>
<section class='blockfield'>
</section>
I faced this problem previously that my code does not work with
$(document).on.....
So firstly you change the duplication of ids as foxinatardis said and test this:
$(document).delegate('.class_off_button', 'click', function (){
//what you want to do
});

Populating string with dynamic data

I have the following line of code inside me JS:
'<a class="txt333 clps" data-toggle="collapse" aria-expanded="false" '+
'href="#collapse_reqConf'+sent+'" '+
'aria-controls="collapse'+sent+'" '+
'data-parent="#accordion_reqConf'+sent+'">'
Which populates var sent and produces the following results (from source view):
<a class="txt333 clps" data-parent="#accordion_reqConf137" aria-controls="collapse137" href="#collapse_reqConf'+sent+'" aria-expanded="false" data-toggle="collapse">
I cannot figure out why the one within href attribute is not being inserted properly...
UPDATE: WORKING ANSWER IN MY LAST COMMENT.
Since you're using jQuery anyways, you try something like the following to create DOM elements using jQuery. Personally, I feel that creating elements using strings of HTML is error-prone, makes the code hard to read and debug. I create the <a></a> element that you are having an issue with using jQuery and append its containing elements using elements created from string.
var inner = '<div class="row">'+
'<div class="col-xs-9 col-sm-8">'+
'<table class="w100p text-success b">'+
'<tr>'+
'<td width="50%" class="nowrap pad10rt">'+ '<i class="fa fa-clock-o fa-lg valignMid xtraSm"></i> 4:00 pm'+'</td>'+
'<td width="50%"><i class="fa fa-user fa-lg valignMid xtraSm"></i> x '+part+'</td>'+
'</tr>'+
'</table>'+
'</div>'+
'<div class="col-xs-3 col-sm-4 text-right">'+
'<i class="indicator fa fa-fw fa-chevron-right"></i>'+
'</div>'+
'</div>';
var attribs = {
"class": "txt333 clps",
"data-toggle": "collapse",
"aria-expanded": false,
"href": "#collapse_reqConf" + sent,
"aria-controls": "collapse" + sent,
"data-parent": "#accordion_reqConf" + sent
};
var elStr = $('<a>').attr(attribs).append($(inner)).prop('outerHTML');
console.log(elStr);

Categories

Resources