Update "progress bar" based on selection in Ractive - ractivejs

I am new to Ractive.js. What i am basically trying to achieve is that based on the id selection(from the combo box),update appropriate progress bar.
In below sample, there are two progress bars and 4 buttons(+25,+10,-25,-10).User can select any progressbar(say "first") and then press any buttons like +25 etc.When the user performs this action, appropriate progressbar should be updated(in this case "first" by say "25").
I have tried but am not sure how to select context based on progressbar selection.In my case,both progress bars get updated irrespective of what i have selected in select box. Please let me know how can i resolve this issue and also tell me if there is a way to clean the code(something like ng-repeat etc)
Please see the code in See full code here....
.progress-bar {
position: relative;
width: 200px;
height: 40px;
border: 1px solid black;
}
.progress-bar-fill {
height: inherit;
background-color: orange;
}
.progress-bar-fill-red {
height: inherit;
background-color: red;
}
.progress-label {
position: relative;
top: 3px;
left: 5px;
color: #000;
}
input[type=range] {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
/* essentially making range slider invisible */
opacity: 0;
}

The trick here is to keep track of which progress bar is selected (which you're doing with the selectedProgress value), and use that to determine which value to update.
Another trick: any time you find yourself writing the same (or similar) code again and again, it's usually a sign that you can abstract something into a function or loop (the so-called Don't Repeat Yourself rule, or DRY). In this case, we can move the progress bars into a repeated section. Having done that, it makes more sense to keep the value of the progress bar in the same object as the name, like { name: 'first', value: 0 }, because then, when we're iterating over the progressbar objects, we can just use {{value}} to refer to that progress bar's value, rather than having to retrieve the value from somewhere else.
By the same token we can avoid re-writing the logic that updates the value, by having a single function (let's call it adjust) and calling it directly from the template:
var ractive = new Ractive({
el: document.body,
template: '#template',
data: {
progressbars: [
// notice no `id` field – in the <select>, we can just
// use the current index
{ name: 'first', value: 0 },
{ name: 'second', value: 0 }
// and so on...
],
amounts: [ +25, +10, -10, -25 ]
},
adjust: function ( d ) {
var selected = this.get( 'selectedProgress' );
if ( selected == null ) return;
var keypath = 'progressbars[' + selected + '].value';
this.add( keypath, d );
}
});
{{#each amounts}}
<button disabled='{{selectedProgress == null}}' on-click='adjust(this)'>{{this > 0 ? '+' : ''}}{{this}}</button>
{{/each}}
Now, whenever the button (which is disabled if you haven't selected a progress bar) is clicked, the adjust function is called with the current amount in the amounts array (i.e. this).
All of which is easier to show than to describe, so here's an updated fiddle: http://jsfiddle.net/rich_harris/k8vpcv27/

Related

CodeMirror Line-Break doesn't add line number - Angular

I'm using code mirror from ngx-codemirror. I want to split the line when it fits to the width of the parent. I have found some solutions to split the like using,
lineWrapping: true
and in styles
.CodeMirror-wrap pre {
word-break: break-word;
}
Using this I was able to split the line but I need to show the line number too.
The line number is not shown for the line that was just split.
This is the stackblitz link to my issue : code-mirror-line-break-issue
Screenshot :
Please help me with this.
This is not feasible using Code Mirror options, as this is something that is a bit counter intuitive that is rarely (ever?) wanted.
Like I said in my comment, say 2 persons discussing on a phone/web chat about a piece of code/json. They will not see the same thing when one mentions a line number to the other if they have different windows/screen sizes
Solution
As a hack, you can create your own elements representing line numbers and place them over the default line numbers.
Here is the stackblitz demo
Note: This a a very basic example. If you change code mirror settings (font size, gutters,...), you might need to tweak the css or do more calculation based on these settings.
component.html
<div class='codeMirrorContainer'>
<ngx-codemirror
#codeMirror
[options]="codeMirrorOptions"
[(ngModel)]="codeObj"
></ngx-codemirror>
<ul class='lineContainer' [style.top.px]="-topPosition">
<li [style.width.px]='lineWidth' *ngFor="let line of lines">{{line}}</li>
</ul>
</div>
component.css
li
{
height: 19px;
list-style: none;
}
.codeMirrorContainer
{
position:relative;
overflow: hidden;
}
.lineContainer
{
position:absolute;
top:0;
left:0;
margin: 0;
padding: 5px 0 0 0;
text-align: center;
}
::ng-deep .CodeMirror-linenumber
{
visibility: hidden; /* Hides default line numbers */
}
component.ts
export class AppComponent
{
#ViewChild('codeMirror') codeMirrorCmpt: CodemirrorComponent;
private lineHeight: number;
public lineWidth;
public topPosition: number;
public lines = [];
codeMirrorOptions: any = ....;
codeObj :any = ...;
constructor(private cdr: ChangeDetectorRef)
{
}
ngAfterViewInit()
{
this.codeMirrorCmpt.codeMirror.on('refresh', () => this.refreshLines());
this.codeMirrorCmpt.codeMirror.on('scroll', () => this.refreshLines());
setTimeout(() => this.refreshLines(), 500)
}
refreshLines()
{
let editor = this.codeMirrorCmpt.codeMirror;
let height = editor.doc.height;
this.lineHeight = editor.display.cachedTextHeight ? editor.display.cachedTextHeight : this.lineHeight;
if (!this.lineHeight)
{
return;
}
let nbLines = Math.round(height / this.lineHeight);
this.lines = Array(nbLines).fill(0).map((v, idx) => idx + 1);
this.lineWidth = editor.display.lineNumWidth;
this.topPosition = document.querySelector('.CodeMirror-scroll').scrollTop;
this.cdr.detectChanges();
}
}

CSS for printing is not applied to dynamically generated HTML

I am trying to print an HTML that comes from server-side. And the main issue that I face now is that css is not applied for some reason. See the fiddle. Is there something I am doing wrong ?
P.S. The JS with frames is used in order to open the print window in the same tab. Previously I ran into trouble that when new tab opened, the JS on the original tab stopped working till I closed the second tab with print content
https://jsfiddle.net/7L9onps1/
#media print {
body * {
visibility: hidden;
}
.test {
visibility: visible;
position: absolute;
left: 0;
top: 0;
background: red;
color: red;
-webkit-print-color-adjust: exact;
}
}
JS:
document.querySelector("#print").addEventListener("click", function() {
var html = '<div class="test">Test</div>';
print(html);
});
function print(html) {
// https://www.sitepoint.com/5-jquery-print-page-options/
document.innerHTML = html;
$('<iframe>', {
name: 'myiframe',
class: 'printFrame'
}).appendTo('body').contents().find('body').append(html);
window.frames['myiframe'].focus();
window.frames['myiframe'].print();
setTimeout(() => { $(".printFrame").remove(); }, 1000);
}
I´m using a libary to do that: https://github.com/DoersGuild/jQuery.print

Make toggle behave like input controls i.e. to respond to space bar key down and keyboard tab action

We have toggle controls as in the below link
https://www.w3schools.com/howto/howto_css_switch.asp
While these take input on mouse click, they don't change state on space key down and when keyboard tab is used these are not highlighted/selected.
How can these be made behave like any regular input control?
I would look for solution in html/css which could be easily applied to any such controls.
Update:
As mentioned in the answer, checkboxes change state on press of spacebar and not enter key.
I found the answer. First add a tab index to the element, so it can be focused. Then you can add this jQuery code.
$('.switch').on('keydown', function(e) {
if(e.keyCode == 13) {
if($(this).children("input").attr('checked')) {
$(this).children("input").attr('checked', false);
} else {
$(this).children("input").attr('checked', true);
}
}
});
I edited the code W3Schools site to add this code. You can view it at https://www.w3schools.com/code/tryit.asp?filename=FHPJRINMFQOH.
Good Luck!! Hope this helps!!
This can be done with css. Since we have to guess how your html and css is structured, i can only provide you something you can work with.
And by the way you change checkbox state with spacebar, not with enter key
label { margin-right: 1rem }
span {
display: inline-block;
width: 2rem;
height: 2rem;
background: rebeccapurple
}
input:focus + label span {
outline: 1px solid red
}
input:checked + label span {
background: red
}
/* https://css-tricks.com/places-its-tempting-to-use-display-none-but-dont/ */
.visuallyhidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
height: 1px; width: 1px;
margin: -1px; padding: 0; border: 0;
}
<input id="check" class="visuallyhidden" type="checkbox">
<label for="check"><span></span></label>
<input id="box" class="visuallyhidden" type="checkbox">
<label for="box"><span></span></label>
This can done using jquery
Since the toggle button is a simple checkbox we can access them using the keypress function
$(document).ready(function(){
$('#mycheckbox').keypress(function(event) {
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == 13) {
clickCheckBox(this);
}
event.stopPropagation();
});
});
function clickCheckBox(box){
var $box = $(box);
$box.prop('checked',!$box.prop('checked'));
}
find the fiddle here

How to set background color to $actionsheet in ionic frameworks

Here is the code, very simple and copy paste from office website
$scope.show = function() {
// Show the action sheet
var hideSheet = $ionicActionSheet.show({
destructiveText: 'Delete Photo',
titleText: 'Modify your album',
cancelText: 'Cancel <i class="icon ion-no-smoking"></i>',
cancel: function() {
// add cancel code..
},
buttonClicked: function(index) {
return true;
}
});
// For example's sake, hide the sheet after two seconds
$timeout(function() {
hideSheet();
}, 2000);
};
I want to change the cancel button have a red color background, how I can achieve it in ionic frameworks?
Easiest way is to look at the markup using your browser (after running ionic serve in your terminal), for example in Chrome ctrl+shift+i, where you can choose the button and see what classes are attached. In your case you'll see something like this:
<div class="action-sheet-group action-sheet-cancel" ng-if="cancelText">
<button class="button ng-binding"
ng-click="cancel()"
ng-bind-html="cancelText">Cancel</button>
</div>
Which has styles that for the parent div, and child button something like this:
.action-sheet-group {
margin-bottom: 8px;
border-radius: 4px;
background-color: #fff;
overflow: hidden;
}
.action-sheet .button {
display: block;
padding: 1px;
width: 100%;
border-radius: 0;
border-color: #d1d3d6;
background-color: transparent;
color: #007aff;
font-size: 21px;
}
Just change these values either in Sass or directly in your styles sheet if you're not using Sass.

Position fixed menu to top

I know how to use position:fixed; but I want, if the page scrolls over it, that it's on the top and on normal state lower.
.menu {
height: 30px;
width: 100%;
border-bottom: 1px solid black;
position: fixed;
top: 0px;
}
If I understand correctly, you want to make a menu fixed after it's scrolled past? If that's the case, see this question.
If that doesn't work for you, consider using code like this, assuming jQuery (actually Sprint but it's about the same for both):
var navigation = $('nav').item(0);
var navigationY = navigation.element.offsetTop;
var navClone = navigation.clone();
$(window).bind('scroll', function() {
var scrollY = (window.pageYOffset || (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop) >>> 0;
if(scrollY > navigationY) {
if(!navClone.element.parentNode || navClone.element.parentNode.nodeType !== 1) {
navigation.after(navClone);
navigation.addClass('fixed');
}
} else if(navClone.element.parentNode) {
navClone.remove();
navigation.removeClass('fixed');
}
});
which I used in a recent project, so just change $('nav') at the top to whatever you need to select your element, e.g. $('.menu').

Resources