Binding multiple HTML properties using WinJS? - windows-8

WinJS allows you to bind HTML properties dynamically at run-time, similar to XAML binding.
<div id="itemTemplate" data-win-control="WinJS.Binding.Template"...>
<h3 data-win-bind="innerText: timestamp"></h3>
</div>
How if I want to also bind the font color style for <h3> as well, how do I achieve that?

Unlike the data-win-options binding which makes use of {key:value,key2:value2} syntax. data-win-binding uses a syntax similar to inline-css styles.
Using property:bindingValue;property2:bindingValue2 etc will allow you bind multiple properties to the same HTML control.
As an example to answer the question above:
<div id="itemTemplate" data-win-control="WinJS.Binding.Template"...>
<h3 data-win-bind="style.color: fontcolor; innerText: timestamp"></h3>
</div>

Lets say you want to switch between green and red color if the timestamp is "important", and you have a field "isImportant" in your model:
HTML:
<div id="itemTemplate" data-win-control="WinJS.Binding.Template">
<h3 data-win-bind="innerText: timestamp; style.color: isImportant MyConverters.colorConverter"></h3> </div>
Then you could use an converter to return the preferred color depending on the boolean isImportant like this:
JS:
WinJS.Namespace.define("MyConverters", {
//Converter function
colorConverter: WinJS.Binding.converter(function (important) {
return important ? "Green" : "Red";
})
});

Related

Link from Object as src to img tag

I want to pass information (link) form Object, and give it as the src to image. Somehow tag doesn't see it. Even though it console log proper link and the link is working.
Object
setup() {
const state = reactive({
flashcardObject: {
linkToGraphic: 'https://static.fajnyzwierzak.pl/media/uploads/media_image/auto/entry-content/785/mobile/dog-niemiecki.jpg'}
})
return{
state
}
}
Where is the bug
<template>
<div>
<div class="ViewFlashcards">
<div class="image_div">
<img class="picture" src="{{state.flashcardObject.linkToGraphic}}"/>
</div>
</div>
</div>
</template>
Thank you for your help!
Use v-bind, like so:
<img v-bind:src="state.flashcardObject.linkToGraphic" class="picture"/>
Full code:
<template>
<div>
<div class="ViewFlashcards">
<div class="image_div">
<img class="picture" v-bind:src="state.flashcardObject.linkToGraphic"/>
</div>
</div>
</div>
</template>
v-bind allows you to bind an (HTML) attribute to a data property or just some JS code. In this case you just pass along your image URL to the src attribute of the <image>.
Note that mustache syntax, {{ something }}, does not work in HTML attributes; it only will work within elements, like <p>{{ something }}</p>.
Also, note that instead of v-bind:attribute, you can omit the v-bind part and just keep the colon, like so: :attribute. This makes it easier to bind attributes.
For more info and examples see the docs
You should require it and use : to bind the image src to the required path if the image is stored in the app :
<img class="picture" :src="require(state.flashcardObject.linkToGraphic)"/>
or :
<img class="picture" :src="state.flashcardObject.linkToGraphic"/>
if the image is hosted online.

How to render VueJs component based child node text?

======Updated with more background=====
I am working on a tool to convert text to a sequence diagram like this:
In the current implementation, the code (on the left) is provisioned programmatically by calling store.dispatch. I would like to make it simpler for other projects to integrate. What I wanted to achieve is to create a web component: <sequence-diagram />. It can be used in this way:
// Format A
<sequence-diagram>
response = BookController.Get(id)
....
</sequence-diagram>
The above DOM element would be rendered as a sequence diagrams (as shown on the right side of the above picture.
For the component to render properly, it needs to know what the "code" is. To pass the code (response = ....) to the component, I know I can use attributes and access it via props like this:
// Format B
<sequence-diagram code="response = ..." />
However, when the code is very long the above format is not as readable (imagine multiline code) as putting the code as child node text. If I use "Format A", how can I get the code content in my web component?
======Original question=====
What I want to implement is like this:
<my-component>
some text
</my-component>
I have managed to make it work by using attributes:
<my-component code="some text" />
Using child node text is much more readable in my case, as the text can be very long.
In the template, it already has a child component. The current template is like
<div> <myChildComponent/> </div>
I don't need to keep the text in the result dom.
I think what you want are slots. (See https://v2.vuejs.org/v2/guide/components.html#Content-Distribution-with-Slots).
The code of your component would look like this:
<div>
<slot></slot>
<myChildComponent/>
</div>
A runnable example
Below we have an alert-box component that displays an error message inside a <div> styled with a red background. This is how we use it:
<alert-box> This email address is already in use. </alert-box>
And it generates HTML that looks like this:
<div>
<strong>Error!</strong>
This email address is already in use.
</div>
See it in action:
Vue.component('alert-box', {
template: `
<div class="demo-alert-box" style="background-color: red; color: white;">
<strong>Error!</strong>
<slot></slot>
</div>
`
})
new Vue({
el: "#app"
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<alert-box> This email address is already in use. </alert-box>
<p> I'm a normal paragraph. </p>
</div>

Using plain JS in Vue.js Component

So, I want to create a navbar and rather than re-invent the wheel, I am using some public code to speed up my MVP dev.
Essentially, I am using this nav-bar code - https://codepen.io/PaulVanO/pen/GgGeyE.
But I am not sure of how I can implement jquery part within my Vue code (I have made a component, copied over html and css, now just need to integrate the jquery functionality within it.)
Here is the Jquery code I need to integrate.
$('#toggle').click(function() {
$(this).toggleClass('active');
$('#overlay').toggleClass('open');
});
It would be really thankful if anyone could help me accomplish with this.
Assuming you have your markup (html and css) as part of one component, getting the toggle to add/remove a class would be really simple, you just need to have a method toggle the active state and a data property to keep the data. An example would be better, so here it goes.
In your component object:
{
data() {
return {
isActive: false
}
},
methods: {
toggleMenu(){
this.isActive = !this.isActive
}
}
}
In your markup you need this
<div class="button_container" id="toggle" :class="{'active': isActive}" #click="toggleMenu">
<span class="top"></span>
<span class="middle"></span>
<span class="bottom"></span>
</div>
------------------------------------
<div class="overlay" id="overlay" :class="{'open': isActive}">
<nav class="overlay-menu">
<ul>
<li >Home</li>
<li>About</li>
<li>Work</li>
<li>Contact</li>
</ul>
</nav>
That should get you going, just note i used the shorthand form for v-on and for v-bind
EDIT:
Here's also a link to an updated pen with the whole example

apply dynamic CSS class from a computed in vue.js on top of other conditional classes

I have this div in my Field.vue component template:
<div class="field"
:class="{
'has-bomb': field.hasBomb && field.isOpen,
'is-open': field.isOpen,
'is-marked': field.isMarked
}"></div>
Now I have a computed that creates a String based on field.x and field.y like this:
computed: {
cssClass () {
return `x${this.field.x}-y${this.field.y}`
}
}
How can I add that generated String as a CSS class to my div?
I tried
<div class="field"
:class="{
'has-bomb': field.hasBomb && field.isOpen,
'is-open': field.isOpen,
'is-marked': field.isMarked,
cssClass
}"></div>
and also
<div class="field"
:class="{
'has-bomb': field.hasBomb && field.isOpen,
'is-open': field.isOpen,
'is-marked': field.isMarked,
cssClass: true
}"></div>
but that just gives me
<div class="field cssClass"></div>
instead of what I need, e.g.:
<div class="field x3-y10"></div>
For this approach, Vue provides so called the Array Syntax class binding, which allow using static or dynamic classes inside an array which is passed to the dynamic html attribute.
For example:
<div :class="['static-class', computedClass, {'dynamic': obj.enabled}]">Test</div>
**REQUIRED IN COMMENTS by #webnoob:** It is also good to know that is possible to use both pure html `class` with vue dynamic `:class` even though in HTML is not valid to use 2 same attributes ([read more in specifications][2]), moreover, nowadays if you try to use multiple same attributes, browsers will just ignore them. But in our case with vue it works because all the dynamic classes will be merged together with the static ones and at the end the element will contain only one class attribute.
Working example:
<div :class="myClass" class="row">Test</div>
But is not possible to use two of the same style (i.e. two dynamic or two static)
Not working example:
<div class="a" class="b"></div> or <div :class="a" :class="b"></div>
This generates errors.

How do I set an element's class using data-win-bind

I'm trying to dynamically set the class of a listview item template:
<div id="semanticZoomTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
<h1 class="semanticZoomItem-Text" data-win-bind="innerText:title;class:contains"></h1>
</div>
But data-win-bind fails to do anything when 'class' is present as a property-name.
Is there a correct way to styling specific items in a listview if indeed I can't change the class with data-win-bind?
You need to set the JavaScript class property, which is not called "class", but "className".