lit-html : is there a way to force re-render of a template? - lit-html

I have been using as lit-html in my own custom web-component library.
I have third party webcompobent :
html`<lottie-player src=${state.url} background="transparent" speed="1" style="width: 100%; height: 100%;" loop autoplay></lottie-player>`
This third party components do not updates itself whenever src attribute is changed on it. I understand, they have not designed it as such.
Is there a way to force lit-html to re-render this, as when I chnage the state.url, instead of deleting old node and creating new one, lit-html keep the same node intact and changes only its attribute.
If there a way to force re-render for this specific template each time ?

Ok, so I solved this issue by :
let b = `<lottie-player src=${state.url} background="transparent" speed="1" style="width: 100%; height: 100%;" loop autoplay></lottie-player>`;
t = html`${unsafeHTML(b)}`;
Concept: B is a string using plain template string. Then then use unsafeHTML directive to create a re-render it!
If any one has any better solution, will be glad to read it too.

Related

How to reuse Material UI styles

I have a custom component and would like to apply the exact same styles as the <Typography> component gets when setting the noWrap prop. The following does work:
<span className="MuiTypography-noWrap">
But there's of course no actual type-checking or "link" to anything here, which means if the name ever changes or is removed in a future version, I won't get any type/build error from it.
Is there a "Material UI way" to reuse/copy these classes? E.g. is there somewhere I can import/access these names from?
I assume you have a reason, but given your example of a span element, I can't help but wonder why you're not just using the MUI component.
I've never done this before, but I was curious and the styles are indeed exported. Not sure if this is a good idea or if there is another way...
import { styles } from '#material-ui/core/Typography/Typography';
const noWrapStyles = styles(theme).noWrap;

How to create custom UI for a MATLAB application?

MATLAB possesses all features I need in my application, except for one - a 21st century look to the applications it builds. The old UI controls with the skin from the 90s just don't cut it anymore. Are there ways to customize the GUI of the compiled window itself? I know of App Designer for MATLAB (which is an alternative for GUIDE as I understood) but that's not close enough. For example, I want a complete flat design look with sprites/buttons/etc drawn in Photoshop for my built application.
Would an external C library/framework be able to build a custom GUI when compiling an application?
I've tried to google this question and it seems like nobody cares about design in the scientific community. I'm not quite sure how to phrase my question, apologies. I hope some of you have a bit of experience with this.
P.S.: Below is the look I'd like to achieve:
As described in my previous comment, and starting from R2019b, you can use uihtml components in new web-based uifigure (introduced in R2016a) to customize style of elements appearing on screen via css + javascript
Here below is a very simple example for a css-styled button:
First the matlab code (TestUiHtml.m):
function [] = TestUiHtml()
%[
% Create the figure and layout
fig = uifigure('Name', 'Test uihtml', 'Color', [1 1 1]);
grid = uigridlayout('Parent', fig, 'ColumnWidth', { '1x', '1x' }, 'RowHeight', {200, '1x' }, 'BackgroundColor', fig.Color);
% Add a uihtml element (that will act like a button using html+css+javascript)
button = uihtml('Parent', grid, 'HTMLSource', 'myway.html', 'DataChangedFcn', #(s,e)onBtnClicked(fig));
% Button layout
button.Layout.Row = 1; button.Layout.Column = [1 2];
%]
end
function [] = onBtnClicked(fig)
%[
uialert(fig, 'World!', 'Clicked', 'Icon', 'info');
%]
end
NB: Above code simply adds in the figure a uihtml component whose property HTMLSource points to the html content you want to have.
Here is the html code to describe the custom uihtml component content (myway.html):
<!DOCTYPE html>
<head>
<link rel="stylesheet" type="text/css" href="myway.css">
<script type="text/javascript" src="myway.js"></script>
</head>
<html>
<body>
<div class="container">
<button class="skewBtn blue" id="btn">Hello!</button>
</div>
</body>
</html>
NB: It is not mandatory to have a fully well-formed html code (i.e. just a <button style="...">Hello</button> would do).
The linked css code to style the html content (myway.css):
body {
background-color: transparent;
}
.container {
display: flex;
justify-content: space-evenly;
align-items: center;
flex-wrap: wrap;
height: 97vh;
}
.container .skewBtn {
width: 180px;
height: 80px;
outline: none;
cursor: pointer;
background: none;
transition: 0.5s;
font-size: 24px;
border-radius: 5px;
font-family: "Lato", sans-serif;
}
.container .skewBtn:hover {
border: none;
color: white;
font-size: 28px;
transform: scale(1.1);
}
.blue {
border: 2px solid #1976D2;
color: #1976D2;
}
.blue:hover {
background-color: #1976D2;
transition: all 0.3s ease-in-out;
}
And finally the javascript code for event/data marshalling between matlab and the html-based component ... or for more advanced programming logic, if any, for the html-content (myway.js):
function setup(htmlComponent)
{
document.getElementById("btn").addEventListener("click", function(event)
{
htmlComponent.Data = 1234; // dummy value to fire event on matlab side
});
}
Marshalling is ensure via the data property of a htmlComponent object which both sides (i.e. matlab/javascript) are listening to for changes. Matlab automatically uses jsonencode/jsondecode in the background so you can pass back and forth almost any structure/values you need directly.
And voilĂ  ... a nice-and-responsive css-styled button in matlab's figure:
It would be of course better to refactor above code as a uibuttonex class modeled on existing uibutton property name/value pairs.
Sarting from R2021a it is eventually possible to add it to app designer library of components as described here (I personally don't use the designer and prefer to code interfaces programmatically).
Some remarks
It is not possible to directly style exiting uibutton, uipanel, uitab, etc... elements => Mathwork does not allow to access uifigure's html nor to inject css/javascript in it easily (see following undocumented-matlab thread and mlapptools project to try to cheat things). For instance a uibutton does not translate to directly <button> markup in uifigure's source but a lot of imbricated <div>, so it is very difficult to style (and will probably change from one release to another).
I would not recommend to create a single uihtml element in the figure and code everything in html+css+javascript, but I would rather recommend to create small and simple custom uibuttonex, etc elements ... else you'll have to deal with a single data blob to connect you interface with the matlab code which can be tricky and difficult to reuse.
Unfortunately it is yet not possible to create custom html-containers in which you can add other child ui-elements (custom or non-custom) ... say bye-bye to create containers similar to uix.GridFlex, uix.CardPanel from the wonderful GUI Layout toolbox or to creating nicely styled uitabex, etc... This is really a missing part !
Looking at source code of uifigure pages, custom ui-elements are also embedded in <iframe></iframe> markups, so it is not possible to inject some global css/javascript code (i.e. you'll have to repeat this for each uihtml element you create). It is not possible (or difficult) then to have multiple uihtml elements to interact with each-other (unless coding everything in a single page or passing through matlab code/events only).
Addendum : Here is a solution to get css-style from parent, unfortunately this does not solve one need to inject this css in the main uifigure source (well this can be done in javascript ... something like if !exist(parent.elements where id="mycss") => parent.document.inject(lalala))
Mathworks is going the good direction with uifigure and html in the background, but it's still a bit too locked for now and missing important containers from the GUI Layout toolbox.
NB: I tried the GUI Layout toolbox elements in uifigure ... some are working (with lot of resizing bugs), other are not working at all (GridFlex). Maybe a new version of the toolbox will come.
Charting
For modern charting you can use javascript libraries like D3js, SciChart, LightningChart, or others!!.
There is some example using D3 on fileexchange

How to combine js lines into one?

Hi I have several js/mootools code in a coffee file that I want to combine together as in
$$("#head").setStyle('border-right-color','#e64626');
$$("#head").setStyle('background','#e64626');
$$("#console").setStyle('border-right-color','#e64626');
$$("#console").setStyle('background','#e64626');
Is it possible to combine this into one line?
Although what #sergio gave you is the correct answer and what you wanted, it's probably the wrong thing to do (though his answer is not at fault, its the question that is off).
Setting element inline styles in JavaScript for effects is just not a very good practice. It has its uses in animation/fx but this does not seem to be the case. The reason is that it breaks cascading due to the high specificity and makes it much more difficult to revert, control or change afterwards. It also makes it harder to skin and restyle your app as there's a clear lack of separation of concerns, style in code is rigid.
You need to solve this via CSS
scenario 1: static, non mutable - not very good due to use of ID rather than classes but:
#head, #console {
border-right-color: #e6426;
background-color: #e6426;
}
scenario 2: dynamic, need to differentiate elements on some event such as click, focus, mouseover - though you can solve most of these with pseudos like :focus or :hover, then abstract this into a class:
css:
.highlight-red {
border-right-color: #e6426;
background-color: #e6426;
}
javascript:
var els = $$('#head,#console');
// on whatever event...
els.addClass('highlight-red');
// ... later
els.removeClass('highlight-red');
you will thank yourself later or your successor will or your client, whatever. this has the added benefit that next time you need to change styling or add more rules to differentiate, you have one place to go to. you can even add transitions / animation effects for evergreen browsers.
You can use setStyles() and pass it a object. You can also use , in the string you pass to $$ to select multiple elements. So it would result into:
$$("#head, #console").setStyles({
'border-right-color': '#e64626',
'background': '#e64626'
});
jsFiddle: http://jsfiddle.net/sevvtsx0/

Split html string into multiple pages

I am trying to develop eBook reader kind of android application. I need to split long html string(sent by server at run-time) into pages on fly based on the screen space available. Html content is an article which could contain text, images, videos etc.I am using WebView to display the html.
Can anyone give me direction towards how this can be achieved.
Thanks in advance.
Doing any sort of HTML/DOM parsing is going to drive you up the wall, I think, and means that you're effectively starting to develop your own HTML layout engine.
It's a better idea to use the CSS3 column functions. Basically, get your content to render within a fixed width-and-height column. This becomes your page. Then shift your content position left to move between pages, and wrap it in a container that will hide overflow elements.
Our HTML will basically be:
<body>
<div id="container">
<div id="content">
CONTENT GOES HERE
<span id="endMarker"></span>
</div>
</div>
<div>
<button id="previous">Previous</button>
<span id="page">Page N of M</span>
<button id="next">Next</button>
</div>
</body>
Our basic CSS is:
#container {
width: 240px;
overflow: hidden;
background-color: yellow;
}
#content {
position: relative;
height: 30em;
-moz-column-width: 240px;
-webkit-column-width: 240px;
column-width: 240px;
-moz-column-gap: 10px;
-webkit-column-gap: 10px;
column-gap: 10px;
}
Now we will set the left CSS property for the #content to switch between pages, in multiples of -250px.
We've only got to work out how many columns our content takes, and we've got paging. How to get css3 multi-column count in Javascript gives a hint: we're going to find it from the left position of #endMarker.
Here's a working example http://lateral.co.za/pages.html, with the first chapter of Moby Dick. It works in Chrome and on Android, but not in Firefox - I think because of differences in the CSS columns implementations. Since we're interested in Android here, the code is good.
The important parts are:
The CSS settings as above.
The addition of a <span id="endMarker"></span> after the content (but within the #content div)
The addition of a #previous and #next button, and a #page span, all outside the #container.
This javascript after jQuery loads:
var _column = 0;
var _columnCount = 0;
var _columnWidth = 240;
var _columnGap = 10;
$(function() {
_columnCount = Math.floor($('#endMarker').position().left/(_columnWidth + _columnGap));
setColumn = function(i) {
_column = i;
document.getElementById('content').style.left = -1 * _column * (_columnWidth + _columnGap);
$('#page').html('Page ' + (_column+1) + ' of ' + (_columnCount+1));
}
$('#next').click(function() {
if (_column==_columnCount) return;
setColumn(_column+1);
});
$('#previous').click(function() {
if (0==_column) return;
setColumn(_column-1);
});
setColumn(0);
});
That's it.
There's room for work. One might want to think about that number of columns calculation, I sort of sucked it from the referenced SO post, but haven't actually thought it through... The width of the container seems to affect the column width of the content, which doesn't entirely make sense to me.
But at least everything seems to be working without having to do any HTML parsing and own layout, at least in Chrome and on Android.
You have to parse the HTML, best would be to use some library where you can access the DOM like in JavaScript. Then you can create a custom layout for the parsed content. Does WebView supports JavaScript? That would be a good start to try with.
Obviously you can not split at arbitrary locations of the HTML file, your have to consider the HTML-Tags. After modifying the DOM or splitting the html you can provide an custom CSS file for the content to display it in a way you like and add some pagination using your library or JavaScript.
Using <span style="display:none"></span> can help you to hide content in a website. Then you don't have to split is physically (it is in memory after loading the page anyway).
Hope that helped a bit. You will not get a full solution here, but maybe you got some ideas. If you find further more specific problems it will be easier to ask more specific questions.

Div as Ajax.ActionLink

Is it possible to create Ajax.ActionLink which has instead of text, the whole DIV?
I'd like to map div on Ajax.ActionLink
I don't think that this will work using the standard MVC Ajax scripts. I believe that the MVC javascript is created to use an <a> element by default. On a different note, embedding a div tag within an <a> is not valid XHTML. What are you trying to achieve?
Using Jquery is probably the easiet way you want to go. As an example:
<div onclick="SomeAjaxFunction()">some div content</div>
function SomeAjaxFunction()
{
$.get('<%= Url.Action("SomeAction", "InSomeController") %>', function(data) {
$('.result').html(data); // assuming a partial view
alert('Load was performed.');
});
}
However, if you are dead set on using MS Ajax, to work with divs, you need to possibly look at the Sys.Mvc.MvcHelpers._asyncRequest function and do some of your own re-wrapping to make it usable. I have not tried or tested this, so use at your own risk. (Stick with the Jquery, there is far better help and support available.)