Display a string in a knockout bound virtual element? - html

Existing HTML looks like such:
<span>
<i class='icon-class'></i> OBJECT NAME HERE
</span>
I realize I can add a span and bind the text value to the object name, but it breaks the existing CSS layout. I could tweak the CSS, but before I go doing that (it's quite a complex template) I wanted to make sure there is not a way to do a virtual element that simply displays a string value.
<!-- ko string: objects.name --><!-- /ko -->
or something would be awesome, but from what I can see in the docs you can only use foreach or if in a virtual element.
Am I missing something or am I going to have to use a span?

You can use text binding:
<!-- ko text: objects.name --><!-- /ko -->
Here is working fiddle: http://jsfiddle.net/3RLfR/

Related

How to comment out knockout code in HTML

Is there any to comment out a knock out code in HTML, since the ko code is already in default html comment block.
<!-- ko if : isEditable() -->
<!-- Edit Mode -->
<div class="edit">Edit mode</div>
<!-- /ko -->
Can I comment the above section in my html
In our project we tend to use <!-- kocomment if : isEditable() --><!-- /kocomment --> syntax which effectively turns ko statement into a simple html comment (knockout does not care for such comments).
Or you may use shorter additions to ko word. Just make sure to comment out both opening and closing statement, there is also risk that this commented comment will not stand out, unless you have some knockout syntax highlighting.
Just change the ko to anything else!
<!-- koc if : isEditable() --> or <!-- kcomment if : isEditable() --> anything other that ko makes it as a comment.
As knockout looks only for html comments that start with ko, anything other than ko on an html comment will simply be a comment.

Behavior of NVDA

I am trying to add live region support in a web page to make NVDA usable with the page. However, I have seen quite a different behavior with aria-live attributes than expected.
I have tried adding a single live region which is hidden and I dump all the messages (each message enclosed in <p> tag) into that region to be read by screen reader. It works fine, but the only problem is that the first message inserted into live region div is never read by the NVDA screen reader. Subsequent messages are read perfectly. This live regions div is created dynamically when the first message is to be announced.
aria-live="assertive" doesn't really interrupt the current flow to announce the message.
I am using knockout in web page. When HTML div, which is marked as live-region, is displayed based on knockout condition, then it is not detected by screen reader.
For example:
<!-- ko if: $data -->
<div aria-live="polite" data-bind="text: $data">
</div>
<!-- ko -->
When page is loaded initially, $data is null. So live-region div is absent. But when data is fetched that div gets inserted. However, NVDA doesn't read the content in added div. Is this expected behavior? Is there any workaround to fix this behavior?
Quick answer, pressed for time.
You must have your live region on the page at page render. This primes the browser to monitor it for updates. Adding the element after the fact only primes the browser, but does not trigger it.
I forked your pen and got it working in the first button (through the browser pronounces "XYZ" as "zeyes"). This is in debug mode so there is no CodePen code in there at all (nor frames) to jack it up:
http://s.codepen.io/aardrian/debug/wgWqVm
Non-debug mode so you cans see the code:
http://codepen.io/aardrian/pen/wgWqVm
Your code puts the aria-live on an element wrapped within a Knockout ko if: statement, so it is not rendered to the page at load:
<p>Last name:
<!-- ko if: lastName -->
<strong aria-live="polite" data-bind="text: lastName"></strong>
<!-- /ko -->
</p>
I tweaked it to put the live region around the ko if: check, and now it is announced when the button is pressed:
<p>Last name:
<div aria-live="polite">
<!-- ko if: lastName -->
<strong data-bind="text: lastName"></strong>
<!-- /ko -->
</div>
</p>
Yes, I put a <div> in a <p>, but that is only for demonstration purposes.
Tested in NVDA 2016.4 / Firefox 50.1.1 and it works as I believe you intend. I did not touch the second one at all.

Thumbnail grid with bootstrap

I'm trying to make responsible grid with thumbnails using bootstrap and knockout. Currently i have the next html:
<div class="row">
<!-- ko if: toys().length == 0 -->
<div>No toys in category</div>
<!-- /ko -->
<!-- ko foreach: toys-->
<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6 previewGridItem">
<a class="thumbnail" data-bind="attr: { href: '#!/toy/' + id }">
<img data-bind="attr: {src: images[0] ? images[0] : '/Content/img/NoImage.jpg' }" />
<span data-bind="text: name"></span>
</a>
</div>
<!-- /ko -->
</div>
Sometimes i'm getting correct grid. But in most cases (ofcourse depending on size of images and length of item's names) i've got something like this:
.
How to properly align items? The most simple answer is to set height of images to constant, but then the proportions of images are ruined. More over, i want images resizing including height. Text are limited by 2 lines per image.
Live demo: JSFiddle
I suggest you to take a look at Gridalicious plugin - it's created exactly for this type of situations. It's also pretty fast, and can be easly adjusted for your needs with built in configurable parameters as well as simply editing uncompressed version of plugin accordingly to your needs.
http://suprb.com/apps/gridalicious/
For now, i solved problem using jQuery plugin mentioned in comment by Artanis. I've also have to use plugin imagesLoaded because i have ajax call which loading images. In result i've written next code:
window.imagesLoaded(".previewGridItem", function(instance) {
$(".previewGridItem").matchHeight();
});
I do not think that it's the best solution, because now i have 40kb (12Kb minimized) libraries only to align images. But for now i can't find a solution only with css.

Wrap html element with Divs from custom directive

I have an <input /> tag which I want to wrap with some specific Div tags. I'm making custom directive in which I want to implement this functionality. But the problem which I'm facing is, element's prepend() method adds the whole tag i.e. it starts and ends before the targeted input tag. Similarly, append() method on element appends the Div inside the input tag, while what I actually want is,
On html:
<input id="oldinput" custom-textbox /> <!-- custom-textbox is my directive -->
After applying directive, in source, I want this:
<div id="mynewdiv> <!-- added from directive -->
<input id="oldinput" custom-textbox /> <!-- present input tag where I'd apply my directive -->
<div id="othernewdiv" /> <!-- new div to be added from directive -->
</div> <!-- end of newly added div from directive -->
But the result after using append() and prepend() functions:
<div id="mynewdiv> </div> <!-- added from directive, div ends here only -->
<input id="oldinput" custom-textbox > <!-- present input tag where I'd apply my directive, doesn't end here -->
<div id="othernewdiv" /> <!-- new div to be added from directive, it's added inside input tag -->
</div> <!-- end of newly added div from directive -->
</input> <!-- Wraps my newly added div -->
Completely strange behavior. Can someone help me with this?
wrap() does exactly what you want:
// wrap the input with a div
element.wrap('<div id="mynewdiv></div> ')
// add the second div
element.parent().append('<div id="othernewdiv" />')
You should take a look at ngTransclude and also the Developper Guide.
Creating a Directive that Wraps Other Elements
We've seen that you can pass in models to a directive using the
isolate scope, but sometimes it's desirable to be able to pass in an
entire template rather than a string or an object. Let's say that we
want to create a "dialog box" component. The dialog box should be able
to wrap any arbitrary content.

Knockout JS - databind to a literal?

Currently I have the following element
<h6 class="header">
Chance of Precipitation: <span data-bind="text: PrecipitationLabel"></span>
</h6>
This works fine, but I don't really need a span tag in my case --the observable only loads for display, so I don't need to update an element. I know I could bind with a computed/dependent variable that combines the "Chance..." text with PrecipitationLabel, but that takes some of the static markup out of the view, which is not ideal.
Is there something similar to Razor's tags to output just a literal?
The functionality you are looking for was added to github 11 days ago. The syntax would be:
<h6 class="header">
Chance of Precipitation: <!-- ko text: PrecipitationLabel --><!-- /ko -->
</h6>
It is not yet included in any published download.
Or you may use this,
<h6 class="header" data-bind="text: 'Chance of Precipitation: ' + PrecipitationLabel()" />