Bootstrap 3.4.1 sanitizer: allow progress-bar inside a popover - javascript

Bootstrap 3.4.1 and 4.3.1 now comes with a sanitizer to perform XSS prevention.
I'm trying to allow all the necessary attributes to render a progress bar inside the popover of an AdminLTE based on bootstrap 3.4.1.
With .popover({sanitize: false}); everything works as expected:
With a custom sanitizer whitelist, as specified on the bootstrap docs, the progress bar is't displayed:
This is the custom whitelist:
var myDefaultWhiteList = $.fn.popover.Constructor.DEFAULTS.whiteList;
myDefaultWhiteList.div = ['role', 'aria-valuenow', 'aria-valuemin', 'aria-valuemax'];
myDefaultWhiteList.span = ['class'];
myDefaultWhiteList.table = ['class'];
myDefaultWhiteList.tbody = [];
myDefaultWhiteList.tr = [];
myDefaultWhiteList.td = ['colspan'];
console.log(myDefaultWhiteList);
$(function () {
$('[data-toggle="popover"]').popover({
whiteList: myDefaultWhiteList
});
});
And this is the content of my popover:
<div class="progress progress-sm active">
<div class="progress-bar progress-bar-success progress-bar-striped" role="progressbar"
aria-valuenow="6" aria-valuemin="0"
aria-valuemax="10"
style="width: 60%">
<span class="sr-only">6/10</span>
</div>
</div>
<div class="no-padding">
<table class="table table-condensed therapy-popover-table">
<tbody>
<tr>
<td>Protocollo N°</td>
<td>837-2019PC</td>
</tr>
<tr>
<td>Codice prescrizione</td>
<td>93xxxx1</td>
</tr>
<tr>
<td>Prescrizione</td>
<td><small>IDROCHINESITERAPIA INDIVIDUALE (9xxxx1) (30')</small></td>
</tr>
<tr>
<td>Data evento lesivo</td>
<td>10/09/2019</td>
</tr>
<tr>
<td>Data prescrizione</td>
<td>10/09/2019</td>
</tr>
<tr>
<td>Priorità</td>
<td>Breve</td>
</tr>
<tr>
<td>Tipo prestazione</td>
<td>Privato</td>
</tr>
<tr>
<td colspan="2"><i class="fa fa-share-square"></i> Vai alla prescrizione</td>
</tr>
</tbody>
</table>
</div>
Does anyone experienced a problem with bootstrap sanitizer and custom whitelist?
In my, everything works (tables, colspan attributes, etc...) except the progress bar...

Shit. I forgot the style attribute.
So the right role is:
myDefaultWhiteList.div = ['style'];
because 'role', 'aria-valuenow', 'aria-valuemin', 'aria-valuemax' are already defined in the default whitelist.

Related

modal code is not working when appended through js in materialize

I am trying to open a modal with a click on the icon.This icon is generated by js in table with respective data but it doesn't work
but when I copy-paste same code in blade.php file it works fine.
I am attaching screenshots as well.
hope could get an answer.
note: using laravel
function actionFormatter(value, row, index) {
if (row.status == '1') {
return [
'<a class="editGreenColor tooltipped modal-trigger" data-tooltip="Edit" href="#modal5">',
'<i title="Edit" class="mdi-content-create small fontSzie1pt5rm"></i>',
'</a> ',
].join('');
}
}
<table data-toolbar="#toolbar" class="table table-striped table-bordered bootstrap-table" data-unique-id="id"
data-toggle="table" data-url="{{url('/branches/')}}/{{ $prantId }}/get" style="font-size: 14px" data-filter-control="true" data-row-style="rowStyle"
id="branchTable" data-pagination="true">
<thead>
<tr>
<th data-field="id" data-align="center" data-width="5%" data-sortable="true">ID</th>
<th id="name" data-field="name" data-width="25%" data-sortable="true" data-formatter="allBranchViewFormatter">Name</th>
<th data-field="id" data-formatter="actionFormatter" >Actions</th>
</tr>
</thead>
</table>
<div id="modal5" class="modal bottom-sheet">
// some codes
</div>
screenshot1
screenshot2
You have to initialize the modal yourself. Check http://materializecss.com/modals.html#initialization
I solved this by adding an onClick function, thanks for help #cris
function openEdit() {
$(".modal").openModal()
}
<a class="editGreenColor tooltipped modal-trigger" data-tooltip="Edit" href="javascript:void(0)" onclick="openEdit()">
<i title="Edit" class="mdi-content-create small fontSzie1pt5rm"></i>

Can't change binding values of custom element in code behind

I am trying to create a Custom Element that allows me to collapse itself from a simple click delegate, but it doesn't seem to work.
I have this code in my js file
import {inject, bindable, bindingMode} from 'aurelia-framework';
export class DataGridCustomElement {
#bindable({ defaultBindingMode: bindingMode.oneTime }) columns = [];
#bindable({ defaultBindingMode: bindingMode.oneTime }) items = [];
#bindable() collpased = true;
collapseClick() {
this.collapsed = !this.collpased;
}
}
And here is my HTML file
<template>
<require from='./data-grid.css'></require>
<div class="collapse-arrow" click.delegate="collapseClick()">
<span class="collapse-icon glyphicon ${collapsed ? 'glyphicon-plus' : 'glyphicon-minus'}" aria-hidden="true"></span>
<span>Order Lines</span>
</div>
<div class="collapse-block" css="${collapsed ? 'display:none;' : 'display:block;'}">
<table class="data-grid">
<thead>
<tr>
<td repeat.for="column of columns">
${column.title}
</td>
</tr>
</thead>
<tbody>
<tr repeat.for="item of items">
<td repeat.for="column of columns">
${item[column.propertyName]}
</td>
</tr>
</tbody>
</table>
</div>
</template>
The crazy thing is it just doesn't seem to at all. It shows collapsed as being false from the get go, even though I set it to true in the class.
I am calling it like so
<data-grid columns.bind="invoiceColumns" items.bind="lineData"></data-grid>
Any ideas? Am I missing something about Custom Elements?
Easy solution. You have a typo in this.collapsed = !this.collpased;.

Meteor JQuery Start Rating Issue

I am getting issues trying to use the follow Meteor Package: dandv:jquery-rateit.
I am using it for a ticket system where each update will have a start rating. But when I have more than 1 comment the second one always return 0 value.
Here is my code:
JS:
Template.rating.events({
'click .rateit': function(e){
var rating = $('#rate').rateit('value');
console.log(rating);
Session.set('UpdateId', this._id);
var UpdateId = this._id;
console.log(UpdateId);
/*Meteor.call('saveRate',rating,UpdateId);*/
return false;
}
});
Template.rating.rendered = function () {
this.$('.rateit').rateit();
}
HTML:
<template name="Update">
{{#each Updates}}
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title" align="center">Update</h3>
</div>
<div class="panel-body">
<table class="table">
<tr>
<td width="15%" nowrap align="left">Created By:</td>
<td width="35%" align="left">{{createdBy.username}}</td>
<td width="15%" nowrap align="left">Created At:</td>
<td width="35%" align="left">{{formatDate createdAt}}</td>
<td width="15%" nowrap align="left">Rating:</td>
<td width="35%" align="left">{{> rating}}</td>
</tr>
<tr>
<td colspan="4">{{description}}</td>
</tr>
</table>
</div>
</div>
{{/each}}
</template>
<template name="rating">
<div class="rateit" id="rate"></div>
</template>
Now when I try to rate the second comment is return 0. Screenshot: http://screencast.com/t/ejaTI98X
No matter what star do I select, it always return 0. I think that the error should be probably in the HTML.
I really appreciate all your help on it. If you have any question just let me know.
Have a great day.
You iterate over Updates and I assume there are more than one update. For each update you call the template {{>rateit}} which then renders a div with id=rate, so you will end up with several divs with the same id, so you don't really know which one $('#rate') you are accessing.
In your event handler you also use the global jQuery handler.
I suggest you use the following pattern instead to scope jQuery local to the templates context
Template.rating.events({
'click .rateit': function(e,template){
var rating = template.$('.rateit').rateit('value');
console.log(rating);
Session.set('UpdateId', template.data._id);
var UpdateId = template.data._id;
console.log(UpdateId);
/*Meteor.call('saveRate',rating,UpdateId);*/
return false;
}
});

table column hover load separate div

I'm having a bit of trouble figuring something simple out. I have a large datatable, and I want that when hovering any column, a specific div (and different for each column) is loaded somewhere on the page, outside the table.
How should I go about that? I'm having trouble defining columns (I'm using jquery dataTables), and then finding a way to load a different image for each column.
Here is my current code that doesn't take columns into account:
$('td').hover(function() {
var myClass = $(this).attr("class");
/* hide any previously loaded div */
$(".loaded").hide();
/* load my new div with the content I need */
$("#"+myClass).show();
});
And the HTML:
<thead>
<tr>
<th class="sp1">SP1</th>
<th class="sp2">SP2</th>
<th class="bb1">BB1</th>
<th class="br1">BR1</th>
<th class="br2">BR2</th>
<th class="br3">BR3</th>
</tr>
</thead>
<tbody>
<tr>
<td class="sp1">xxx</td>
<td class="sp2">xxx</td>
<td class="bb1">xxx</td>
<td class="br1">xxx</td>
<td class="br2">xxx</td>
<td class="br3">xxx</td>
</tr>
....
</tbody>
Thanks!
Im not sure if this is what you want, but check it out:
This code will show the name of the div you are hovering in another div.
https://jsfiddle.net/5jy071t5/4/
HTML
<ul>
<li name="first">Hoover me</li>
<li name="second">And me</li>
</ul>
<div id="output"></div>
Javascript
$( "li" ).hover(
function() {
$("#output").html($(this).attr("name"));
//you can also load an image if you like
}, function() {
$("#output").html("");
}
);
It works as charm. Maybe you were missing either id or class.
$('td').hover(function() {
var myClass = $(this).attr("class");
/* hide any previously loaded div */
$(".loaded").hide();
/* load my new div with the content I need */
$("#"+myClass).show();
});
.loaded{
display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th class="sp1">SP1</th>
<th class="sp2">SP2</th>
<th class="bb1">BB1</th>
<th class="br1">BR1</th>
<th class="br2">BR2</th>
<th class="br3">BR3</th>
</tr>
</thead>
<tbody>
<tr>
<td class="sp1">xxx</td>
<td class="sp2">xxx</td>
<td class="bb1">xxx</td>
<td class="br1">xxx</td>
<td class="br2">xxx</td>
<td class="br3">xxx</td>
</tr>
</tbody>
</table>
<div id="sp1" class="loaded">sp1</div>
<div id="sp2" class="loaded">sp2</div>
<div id="bb1" class="loaded">bb1</div>
<div id="br1" class="loaded">br1</div>
<div id="br2" class="loaded">br2</div>
<div id="br3" class="loaded">br3</div>

Putting table into Bootstrap popover

I have a Bootstrap popover and I'm trying to put a table into it but then it doesn't show up when I click on it. This is the first time attempting HTML inside a popover so I'm unsure how to go about doing it correctly. Thanks!
$(function(){
$("[data-toggle=popover]").popover({
html : true,
content: function() {
var content = $(this).attr("data-popover-content");
return $(content).children(".popover-body").html();
},
title: function() {
var title = $(this).attr("data-popover-content");
return $(title).children(".popover-heading").html();
}
});
});
<a role="button" class="btn btn-link btn-item black-text" data-toggle="popover" data-trigger="focus" data-placement="top" title="Currency Converter" data-content="Displayed rates are only for informational purposes and do not reflect on the actual rates you may be charged by the financial institution handling your transaction.
<table class='table table-condensed table-bordered'>
<tr><td>Euro</td><td>€79,123</td></tr>
<tr><td>GB Pound</td><td>£46,536</td></tr>
<tr><td>AU $</td><td>$123,456</td></tr>
</table>LLC accepts payment in US Dollars only. Rates do not include taxes, duties, shipping, insurance, or any other expenses associated with the purchase."><i class="fa fa-exchange"></i> Currency converter</a>
This worked for me:
$(function() {
$.fn.popover.Constructor.Default.whiteList.table = [];
$.fn.popover.Constructor.Default.whiteList.tr = [];
$.fn.popover.Constructor.Default.whiteList.td = [];
$.fn.popover.Constructor.Default.whiteList.div = [];
$.fn.popover.Constructor.Default.whiteList.tbody = [];
$.fn.popover.Constructor.Default.whiteList.thead = [];
$('[data-toggle="popover"]').popover({
html: true,
container: 'body'
})
})
Example : http://jsfiddle.net/z824fn6b/320/ use table in popover and toggle button
Popover Example
<div id="a1" class="hidden">
<div class="popover-heading">Title <span style="float:right;cursor:pointer;" class="fa fa-times" data-toggle="popover"></span></div>
<div class="popover-body">
<table style="width:100%">
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</div>
</div>
$(function() {
$("[data-toggle=popover]").popover({
html: true,
content: function() {
var content = $(this).attr("data-popover-content");
return $(content).children(".popover-body").html();
},
title: function() {
var title = $(this).attr("data-popover-content");
return $(title).children(".popover-heading").html();
}
});
});
This may help:
HTML:
<div id="myPopoverContent">
<table border="1" style="width:100%">
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
jQuery:
$('[data-toggle=popover]').popover({
content: $('#myPopoverContent').html(),
html: true
}).click(function() {
$(this).popover('show');
});
Working jsFiddle: http://jsfiddle.net/ja3f6p4j/19/
Here is how I did it:
HTML:
<div class="span12" style="margin-top: 150px;width:100%">
<a tabindex="0" role="button" data-trigger="focus" class="btn-sm btn-info" data-placement="top" id="commentPopover"><i class="fa fa-comments" ></i> View</a>
<!-- Popover 2 hidden content -->
<div id="commentPopoverHiddenContent" style="display: none">
<div>
<table border="1" style="width:100%">
<tr>
<th width="30%">Comment date</th>
<th width="70%">Comment</th>
</tr>
<tr>
<td>12/03/2015 16:45</td>
<td>*Username - Testing1</td>
</tr>
<tr>
<td>12/03/2015 16:55</td>
<td>*Username - Testing2</td>
</tr>
<tr>
<td>12/03/2015 17:13</td>
<td>*Username - Testing3</td>
</tr>
</table>
</div>
</div>
<!-- Popover 2 hidden title -->
<div id="commentPopoverHiddenTitle" style="display: none">
Error comments
</div>
</div>
JQuery:
$(function(){
// Enabling Popover Example 2 - JS (hidden content and title capturing)
$("#commentPopover").popover({
html : true,
content: function() {
return $('#commentPopoverHiddenContent').html();
},
title: function() {
return $('#commentPopoverHiddenTitle').html();
}
});
});
Here is a fiddle: http://jsfiddle.net/5bsykcqt/
As nothing was working well for me and the answers were old, this did the trick:
const list = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'))
list.map((el) => {
let opts = {
animation: false,
}
if (el.hasAttribute('data-bs-content-id')) {
opts.content = document.getElementById(el.getAttribute('data-bs-content-id')).innerHTML;
opts.html = true;
opts.sanitizeFn = function (content) {
return content
}
}
new bootstrap.Popover(el, opts);
})
As alluded to at the bottom of this page: Bootstrap 5 Documentation
You can set your own sanitize function, so if you just return what was provided, nothing is removed. Boom
With CSS3 there is a simpler solution: you can use the following display attributes to simulate a table behavior
.popover_container{
display: table;
}
.popover_row{
display: table-row;
}
.popover_column1{
display: table-cell;
text-align: left;
}
.popover_column2{
display: table-cell;
text-align: left;
}
and then build the popover content
$popover_content = "<div class='popover_container'>
<div class='popover_row'>
<div class='popover_column1'></div>
<div class='popover_column2'></div>
</div>
</div>";
and use it in your HTML
echo ('<span class="material-symbols-outlined" data-bs-html="true" data-bs-toggle="popover" data-bs-trigger="hover" title="your titile" data-bs-content="'.$popover_content.'">youricon</span>')

Categories

Resources