Angular Material: mat-checkbox vertical alignment of checkbox - angular-material

I can't seem to override the defaults to vertically align the checkbox relative to the checkbox label. Searched for a while but nothing has worked. See example image:
Should be like:
Have tried the following:
.mat-checkbox-inner-container {
margin: none;
}
HTML:
<label><b>Home Type</b></label>
<mat-checkbox>Entire place<br><small class="text-muted">Have a place to yourself</small></mat-checkbox>
<mat-checkbox>Private room<br><small class="text-muted">Have your own room and share some common spaces</small></mat-checkbox>
<mat-checkbox>Shared room<br><small class="text-muted">Stay in a shared space, like a common room</small></mat-checkbox>

Similar to Craig's answer but as a descendant of .mat-checkbox.mat-accent to spare the need of using "!important"
.mat-checkbox.mat-accent .mat-checkbox-inner-container {
margin: 2px 8px auto 0;
}
or using sass/less
.mat-checkbox.mat-accent {
.mat-checkbox-inner-container {
margin: 2px 8px auto 0;
}
}

Just run into the same problem. I used the following to solve it (unfortunately needs the dreaded !important):
.mat-checkbox-inner-container {
margin: 2px 8px auto 0 !important;
}
I found I had to adjust the top margin (2px in this case) to get the layout beside the label to look correct.

I was able to achieve this (I'm using Angular/Material 7.x) by resetting the margins the checkbox container uses.
Note that I have had to apply an additional translateY to account for the box's border-width, and reset the wrap on the label so the text doesn't try to stay on one line.
your.component.scss
:host {
::ng-deep {
.mat-checkbox-inner-container {
margin-top: initial;
margin-bottom: initial;
transform: translateY(2px); // value of checkbox border-width
}
.mat-checkbox-label {
white-space: normal; // wrap label text
}
}
}
StackBlitz Fiddle

I know this is old, but below worked for me – I honestly didn't even know auto worked with vertical alignment, but I guess it does 🤷🏽‍♂️:
.mat-checkbox-inner-container {
margin-top: 0;
}

<div>
<h1>LABEL CHECKBOX</h1>
<mat-checkbox class="mat-checkbox-layout"><strong>FINE</strong>Lorem ipsum dolor sit amet consectetur adipisicingelit. Optio vitae molestiae nemo magni odio voluptate corporis veniam sapiente earum fugiat rem,maiores et placeat qui iure, nobis ipsam sintenim.</mat-checkbox>
<mat-checkbox class="mat-checkbox-layout"><strong>OK</strong>Lorem ipsum dolor sit amet consectetur adipisicing elit.Optio vitae molestiae nemo magni odio voluptate corporis veniam sapiente earum fugiat rem, maiores et placeat qui iure, nobis ipsam sintenim.</mat-checkbox>
</div>
And the CSS is this (I create css class identically with angular css class)
.mat-checkbox-layout {
text-align: justify;
}
::ng-deep .mat-checkbox-layout .mat-checkbox-layout {
white-space: normal !important;
}

:host {
::ng-deep {
.mat-checkbox-layout {
align-items: end!important;
}
.mat-checkbox-label {
white-space: normal; // wrap label text
}
}
}

There is a fast solution which is not related to ng-material
you can put your "mat-checkbox" into "li" element and align your "ul" by setting the number of columns like this:
<ul style="columns:2">
<li>
<mat-checkbox>Entire place<br><small class="text-muted">Have a place to yourself</small></mat-checkbox>
</li>
<li>
<mat-checkbox>Private room<br><small class="text-muted">Have your own room and share some common spaces</small></mat-checkbox>
</li>
<li>
<mat-checkbox>Shared room<br><small class="text-muted">Stay in a shared space, like a common room</small></mat-checkbox>
</li>
</ul>

Related

highcharts - inconsistent number of yAxis gridlines

can someone explain why number of yaxis gridlines is less in exported svg rather than in the browser version? Is this happening because of margin update? if so, why it updates margin, but leaves old number of gridlines, shouldn't it be updated as well?
Here is my fiddle http://jsfiddle.net/sabira/r0zvouyp/
Thank you in advance!
Highcharts.chart('container', {
chart:{
events: {
load: function(){
const chart = this;
const {title, yAxis} = chart;
setRightDy(title);
const ticks = chart.yAxis[0].ticks;
let topTick = null;
for(let tick in ticks){
if(ticks[tick].isLast) {
topTick = tick;
}
}
const tickY = ticks[topTick].label.xy.y;
const extraMargin = chart.plotTop-tickY + 10;
const currentMargin = chart.title.alignOptions.margin;
chart.title.update({
margin: currentMargin+extraMargin
}, true, false, false)
}
}
},
title: {
align: 'left',
text: `
<span class='titleText' style="font-weight: 500; font-size: 12.6px; font-family: Retina; fill:black"> Lorem ipsum dolor sit amet </span><br>
<span class='dekText' style="font-size: 8.4px; fill: black; font-weight: 300; font-family: Retina"> Integer quis pharetra tellus. Cras tincidunt libero id dignissim convallis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</span><br>
<span class='subdekText--strong' style="font-weight: 500; font-size: 8.4px; font-family: Retina; fill:black">Sed aliquam ligula in pretium lobortis.</span>
<span class='dekText' style="font-size: 8.4px; fill: black; font-weight: 300; font-family: Retina"> Integer quis pharetra tellus. Cras tincidunt libero id dignissim convallis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</span><br>
<span class='subdekText--strong' style="font-weight: 500; font-size: 8.4px; font-family: Retina; fill:black">Sed aliquam ligula in pretium lobortis.</span>
`,
widthAdjust: -40,
margin: 20,
},
exporting: {
scale: 1
},
yAxis: {
labels: {
align: 'left',
x: 0,
y: -4
}
},
series: [{
data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
}],
});
According to comments - your case is more complicated, but I think that a good solution is do also a yAxis.tickAmount update with a current ticks amount to do not calculate them again while the chart is initializing for exporting. See:
Demo: https://jsfiddle.net/BlackLabel/wju68av5/
chart.update({
title: {
margin: currentMargin + extraMargin
},
yAxis: {
tickAmount: chart.yAxis[0].tickPositions.length
}
}, true, false, false)
The problem which you are struggling to is that you set the new margin after the initial load, which changes and animate the chart. However, the export server renders a new chart with a options which you used to set but without loading the load callback, because there is no delay time to do it.
Why don't you just set the calculated margin as a fixed value in the title.margin object and set the wanted amount of ticks to get it? The visual output is the same.
Demo: https://jsfiddle.net/BlackLabel/owr6f7z2/
yAxis: {
labels: {
align: 'left',
x: 0,
y: -4
},
tickAmount: 7
},
API: https://api.highcharts.com/highcharts/yAxis.tickAmount
If this answer wouldn't fit your requirements please describe more precisely what do you want to achieve.

jsPDF fromHTML in Angular: addImage does not support files of type 'UNKNOWN'

I know there are other issues with the error "addImage does not support files of type 'UNKNOWN'", but the difference is that I'm not using addImage directly, but fromHTML to convert an HTML that contains images in an Angular 5+ app.
Curiosly, the images by themselves are not the problem, because they are successfully converted to PDF in this fiddle which uses simple jQUery instead of Angular. So the problem lays in the NPM version of the jsPDF code. Maybe that version of the code does not support images in formats other than PNG?
In this particular case, I don't have control over the images, I only need grab the HTML section and convert it to PDF.
The error message is:
ERROR Error: addImage does not support files of type 'UNKNOWN', please ensure that a plugin for 'UNKNOWN' support is added.
at Object.x.addImage (jspdf.min.js:50)
at k (jspdf.min.js:202)
at jspdf.min.js:202
at l (jspdf.min.js:202)
at Image.i.onerror.i.onload (jspdf.min.js:202)
at Image.wrapFn (zone.js:1188)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:16147)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
The TS code is:
#ViewChild('content') recipeView: ElementRef;
downloadPDF() {
const doc = new jsPDF();
const specialElementHandlers = {
'#editor': function (element, renderer) {
return true;
}
};
const content = this.recipeView.nativeElement;
doc.fromHTML(content, 15, 15, {
'width': 190,
'elementHandlers': specialElementHandlers
}, (dispose) => {
doc.save('test.pdf');
});
}
<div class="row" #content>
<h1>The Title</h1>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Eos, modi dolores? Aliquam cum fuga vero velit! Vel
temporibus natus quasi accusantium! Recusandae quaerat qui exercitationem, debitis omnis deserunt dolorem non.</p>
<br />
<img src="http://a5.mzstatic.com/eu/r30/Purple3/v4/3d/57/31/3d573127-31d5-e4a9-9f8e-986c4616d467/icon175x175.png"
alt="" width="175" height="175">
<img src="https://http2.mlstatic.com/corte-para-hallacas-produccion-nacional-60-unidades-para-60-D_NQ_NP_869908-MLA25589543992_052017-F.webp"
alt="" width="175" height="175">
<img src="https://4.bp.blogspot.com/-C-PxcAwhHXo/WlWDzAmHB7I/AAAAAAAAG8k/hblgAA_HrIIYW_VPzVNuXb7ZjFnxKpduwCLcBGAs/s1600/como-hacer-empanadas-venezolanas.jpg"
alt="" width="175" height="175">
<br />
</div>
<button class="btn" (click)="downloadPDF()">PDF</button>

jquery for restricting words to be displayed

im trying to restrict 120 characters to be displayed.while the rest should be represented as "(more..)".which is make clickable to view the entire content.when i enter desc with space..the "(more..)" moves to the second..if i dont use space...it moves to the first line.
<h:outputScript>interaction360();
function interaction360(){
$(document).ready(function(){
var maxLength = 120;
$(".show-read-more").each(function(){
var myStr = $(this).text();
if($.trim(myStr).length > maxLength){
var newStr = myStr.substring(0, maxLength);
var removedStr = myStr.substring(maxLength, $.trim(myStr).length);
$(this).empty().html(newStr);
$(this).append('<span class="more-text"> (more...) </span>');
}
});
$(".more-text").css("color","blue");
});
}
Live Demo Link : CodePen
HTML code :
<span class="more">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</span>
CSS Code :
.morecontent span { display: none; }
.morelink { display: block; }
jQuery Code:
$(document).ready(function() {
// Configure/customize these variables.
var showChar = 120; // How many characters are shown by default
var ellipsestext = "...";
var moretext = "Show more ...";
var lesstext = "Show less";
$('.more').each(function() {
var content = $(this).html();
if(content.length > showChar) {
var c = content.substr(0, showChar);
var h = content.substr(showChar, content.length - showChar);
var html = c + '<span class="moreellipses">' + ellipsestext+ ' </span><span class="morecontent"><span>' + h + '</span> ' + moretext + '</span>';
$(this).html(html);
}
});
$(".morelink").click(function(){
if($(this).hasClass("less")) {
$(this).removeClass("less");
$(this).html(moretext);
} else {
$(this).addClass("less");
$(this).html(lesstext);
}
$(this).parent().prev().toggle();
$(this).prev().toggle();
return false;
});
});
Hope it will work for you.

jQueryUI Sortable - Unable to drag large elements to the top or bottom if containment and handle set

For the problem I'm trying to solve, I have a table with unique content for each row. The rows are allowed to be reordered via a handle, and the content of each row is not always of uniform height. Sometimes large amounts of text and / or images appear within a row.
There can also be multiple tables with rows that can be reordered, so I'm using the containment property to prevent dragging into other zones and other problematic issues that occur when dragging outside the desired area.
The problem is when I attempt to drag a "tall" row to the top or bottom of the order when the top and bottom are "short" by comparison. Essentially I am not allowed to drag tall rows to the these positions. I have searched for a solution and have come up short. Any help would be appreciated.
Working example here: http://jsfiddle.net/jeffvoigt/XyPzf/
Neither of the two middle rows can be dragged to the top or bottom of the list.
HTML:
<div class="container">
<table id="sortable">
<tr class="odd">
<td><p>[=]</p></td>
<td>Single Line of Text</td>
</tr>
<tr class="even">
<td><p>[=]</p></td>
<td>Aenean porta, tellus quis auctor elementum, risus ante ornare augue, eu elementum nunc libero ut nisi. Pellentesque sed vestibulum tellus. Proin convallis enim eget felis iaculis viverra vestibulum lorem semper. Aliquam imperdiet viverra lorem, ut dignissim felis laoreet vel. Suspendisse fermentum neque eu est vestibulum bibendum. Maecenas dignissim egestas tempor. Ut tincidunt metus sed felis ornare nec sollicitudin risus gravida. Duis vitae mauris quis risus ultricies malesuada. Nulla facilisi. Phasellus fringilla, arcu eget congue sollicitudin, lorem elit ullamcorper ante, non fermentum orci mauris at tellus. Maecenas suscipit sodales molestie. Mauris luctus porta dui non volutpat.</td>
</tr>
<tr class="odd">
<td><p>[=]</p></td>
<td><img src="http://www.google.com/intl/en_ALL/images/logos/images_logo_lg.gif" /></td>
</tr>
<tr class="even">
<td><p>[=]</p></td>
<td>Single Line of Text</td>
</tr>
</table>
</div>
Javascript:
$( "#sortable tbody" ).sortable({
axis: "y",
containment: ".container",
cursor: "move",
handle: "p"
});
I faced the same issue. This is the quick solution:
$('.collections').sortable({
handle: 'h3',
axis: 'y',
containment: 'parent',
items: '.collection',
cursor: 'move',
tolerance: 'pointer',
scroll: true,
beforeStop: function(event, ui) {
var lastElemTop = $('.collections .collection:last-child').position().top;
var currElemTop = ui.position.top;
var currElemHeight = ui.item.height();
if (currElemTop + currElemHeight * 2 > lastElemTop) {
$('.collections .collection:last-child').insertBefore(ui.item);
}
}
});
The problem is the placement of your handle determines the Y position of the sort in relation to the handle it is on top of. So, to demonstrate, go to jsFiddle and add a valign=top to your big text area. The handle moves to the top of the sortable element, and when you drag it to the top where the short line of text is it will snap into place, but you cannot get it to sort to the bottom. However, if you update the fiddle to be valign=bottom, you may snap it to the bottom but not the top.
Solutions would be to either make your entire content area a sortable handle or perhaps move your handles out to the left of the content (making that the 'sortable' area only) and drag only the handles (not the content), then allow the the content area to update upon a new sort.
Basically, it needs to be some how re-envisioned or designed to function properly.
I encountered this very same problem. It seems like this only happens when there is no content or spacing beneath the jQuery Sortable list.
Just adding some spacing (e.g. <div id="end-of-page-spacer" style="height: 500px;"></div>) allowed me to drag large rows beneath smaller rows situated at the bottom of the list.

Highlight on a autocomplete with XML

I am creating a search with autocomplete based on a XML file.
I would like when the user enter a word, the text will be hightligh.
What I have done so far :
$(function() {
function log( message ) {
$( "<div/>" ).text( message ).prependTo( "#log" );
$( "#log" ).scrollTop( 0 );
}
$.ajax({
url: "ecole.xml",
dataType: "xml",
success: function( xmlResponse ) {
var data = $( "school", xmlResponse ).map(function() {
return {
value: $( "name", this ).text() + ", " +
( $.trim( $( "adress", this ).text() ) + ", " + $( "description", this ).text() || "(unknown article)" ),
id: $( "id", this ).text(),
text: $( "description", this ).text()
};
}).get();
$( "#birds" ).autocomplete({
source: data,
minLength: 0,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.value + ", Id: " + ui.item.id + ", Text: " + ui.item.text :
"Nothing selected, input was " + this.value );
},
});
}
});
});
I don't really understand how to do to highlight the text.
I use this code :
$(function() {
highlight: function(match, keywords) {
keywords = keywords.split(' ').join('|');
return match.replace(new RegExp("("+keywords+")", "gi"),'<b>$1</b>');
}
});
But I don't really now why and it doesn't work
Here's my HTML / PHP :
<div id="RecentEdition">
<?php
$schools = simplexml_load_file('ecoles.xml');
foreach ($schools->RecentEdition as $RecentEdition):
foreach ($RecentEdition->school as $school): ?>
<figure>
<img src='<?php echo "{$school->image} \n"; ?>' title='' />
<figcaption>
<h3>Contents</h3>
<p class="over">
<ul>
<?php foreach ($school->content as $content): ?>
<?php foreach ($content->chap as $chap): ?>
<li><?php echo "{$chap} \n"; ?></li>
<?php endforeach; ?>
<?php endforeach; ?>
</ul>
</p>
<p class="go">
View »
</p>
</figcaption>
</figure>
<?php endforeach; ?>
<?php endforeach; ?>
</div>
And here's my XML:
<?xml version="1.0" encoding="utf-8"?>
<schools>
<RecentEdition>
<school>
<name>École1</name>
<id>1</id>
<link>./Marlburian0809/index.html</link>
<image>./img/zine.jpg</image>
<content>
<chap link="./Marlburian0708/#/2/">The Master's Speech</chap>
<chap link="./Marlburian0809/#/8/">College Community</chap>
<chap link="./Marlburian0809/#/50/">Trips n Expeditions</chap>
<chap link="./Marlburian0809/#/64/">Creative Arts</chap>
<chap link="./Marlburian0809/#/92/">Sports</chap>
</content>
<description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer luctus porta turpis, id congue nisi dapibus nec. Maecenas pulvinar blandit turpis, sit amet viverra arcu convallis id. Donec varius blandit orci nec molestie. Cras auctor, metus eget volutpat hendrerit, massa nibh tempor nunc, volutpat ultrices nibh eros vestibulum nulla. Aenean libero risus, auctor sed blandit ut, tincidunt non est. Nullam bibendum nunc non tortor eleifend consectetur. Proin porttitor, diam ac varius semper, leo odio mattis erat, id luctus ligula libero eu mi. Proin et lacus ligula. Quisque non consequat mauris. Morbi dolor mi, dapibus a condimentum ac, luctus at elit. Praesent sit amet felis at magna sagittis pharetra et vitae neque.
</description>
</school>
</RecentEdition>
</schools>
And an another question.
If I have a big text in my autocomplete e.g :
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis
vulputate nibh urna. Aliquam in arcu vel diam malesuada malesuada. Ut
volutpat hendrerit sollicitudin. Quisque vestibulum adipiscing
rhoncus. Curabitur laoreet interdum tempus. Aliquam sit amet urna quis
dui rhoncus venenatis iaculis id arcu. Proin sit amet tincidunt est.
Aenean ut tellus lectus. Vestibulum ac enim orci.
I would like that if you write the world « Interdum tempus », the result display :
« …laoreet interdum tempus. Aliquam sit… »
Is it possible ?
Many thanks for you help.
You might be confusing AutoComplete and Search Term Highlighting. Do you want to:
Slowly reveal possible text choices as the user types more letters (i.e. Google Suggestions)
-OR-
Highlight the already searched for term in a search results page
Or maybe you want to do both, but it looks like you're talking about Highlighting from the sample code, although your question is about AutoComplete...
Anyway here's some code for Autocomplete of the description and Search Term highlighting:
<?php
$q = filter_var($_REQUEST['q'], FILTER_SANITIZE_STRING);
$query = (isset($q) && !empty($q)) ? $q : "";
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Autocomplete/SearchHighlighting Example</title>
<link type="text/css" href="css/ui-lightness/jquery-ui-1.8.20.custom.css" rel="stylesheet" />
<style type="text/css">
span.highlighted {
background-color: #FFF6C6;
font-weight: bold;
}
span.term0 {
color: #161633;
}
span.term1 {
color: #331616;
}
span.term2 {
color: #163316;
}
</style>
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.20.custom.min.js"></script>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style type="text/css">
header, section, footer, aside, nav, article, figure, figcaption, audio, video, canvas { display:block; }
</style>
</head>
<body>
<form id="search" name="search">
<label for="q">Search: </label><input type="text" id="q" name="q" value="<?php echo $query; ?>" placeholder="Enter a search term" />
</form>
<div id="RecentEdition">
<?php
$schools = simplexml_load_file('ecoles.xml');
foreach ($schools->RecentEdition as $RecentEdition):
foreach ($RecentEdition->school as $school): ?>
<figure>
<img src='<?php echo "{$school->image} \n"; ?>' title='' />
<figcaption>
<h3>Contents</h3>
<p class="over">
<ul id="results">
<?php foreach ($school->content as $content): ?>
<?php foreach ($content->chap as $chap): ?>
<li><?php echo "{$chap} \n"; ?></li>
<?php endforeach; ?>
<?php endforeach; ?>
</ul>
</p>
<p class="desc"><?php echo "{$school->description} \n"; ?></p>
<p class="go">
View »
</p>
</figcaption>
</figure>
<?php endforeach; ?>
<?php endforeach; ?>
</div>
<script type="text/javascript">
$(function() {
//Autocomplete
$("#q").autocomplete({
//define callback to format results
source: function(req, add){
//pass request to server
$.getJSON('search.php?callback=?', req, function(data) {
var suggestions = []; //create array for response objects
//process response
$.each(data, function(i, terms){
suggestions.push(terms.term);
});
add(suggestions); //pass array to callback
});
},
//define select handler: Search Term Highlighting function
select: function(match, keywords) {
var rawSearchString = $('#q').val().replace(/[a-zA-Z0-9\?\&\=\%\#]+s\=(\w+)(\&.*)?/,"$1"); // Return sanitized search string if it exists (term should be FIRST URL PARAMETER)
var searchString = rawSearchString.replace(/ /g,"\|").replace("?term=",""); // Replace '+' and '%20' with '|' for regex
var searchTerms = searchString.split('|'); // Split search terms on '|' and iterate over resulting array
for (var j in searchTerms) {
var regex = new RegExp(">([^<]*)?("+searchTerms[j]+")([^>]*)?<", "ig"); // this regex is the secret, it prevents text within tag declarations from being affected
var tempHTML = $('#RecentEdition').html(); // Do regex replace
$('#RecentEdition').html(tempHTML.replace(regex, '>$1<span class="highlighted term'+j+'">$2</span>$3<')); // Inject span with class of 'highlighted termX' for term highlighting
}
}
});
});
</script>
</body>
</html>
And the PHP search file (call it "search.php") using xPath:
<?php
header('content-type: application/json; charset=utf-8');
$term = urldecode($_REQUEST['term']);
$callback = $_GET["callback"];
$html = new DOMDocument();
#$html->load("ecoles.xml");
$xpath = new DOMXPath($html);
$query = "//schools/RecentEdition/school/description[contains(.,'".$term."')]";
$nodelist = $xpath->query($query);
$i = 0;
foreach ($nodelist as $n) {
$result = trim($n->nodeValue);
$resultArray[$i] = array( "term" => str_replace('"',"'",substr($result,strpos($result,$term),25)) );
$i++;
}
$resultJSON = json_encode($resultArray);
echo $callback."(".$resultJSON.")";
?>
DEMO here:
http://bcmoney-mobiletv.com/widgets/autocomplete/

Resources