Can I bind data to data-win-options? - windows-8

I use the control MicrosoftNSJS.Advertising.AdControl in the ItemTemplate of a ListView.
I would like to bind some datas to the following data-win-options properties : ApplicationId and AdUnitId
The source datas are correctly set and are visible in my item template, I can display them with an h2 + a classic data-win-bind on innerText property
Ads are displayed correctly if I put directly static IDs in html code but these IDs need to be loaded from a config file...
Is it possible ? Thanks
If it's not possible, can I modify directly the item template in the JS code before to be injected in the listview ?

Come to find out this is possible (I was trying to do something similar)
The syntax for the control properties must be prefixed with winControl.
Example (I'm setting the application id here but binding the html element's className and the ad control's adUnitId)
<div id="adItemTemplate" data-win-control="WinJS.Binding.Template">
<div data-win-bind="className:css; winControl.adUnitId: adUnitId"
data-win-control="MicrosoftNSJS.Advertising.AdControl"
data-win-options="{ applicationId: 'd25517cb-12d4-4699-8bdc-52040c712cab'}">
</div>
</div>

I finally found a way to perform this without real binding, by using the itemTemplateSelector function like this :
function itemTemplateSelector(itemPromise)
{
return itemPromise.then(function (item)
{
if (item.type == "ad")
{
var template = _$(".adTemplate").winControl.render(item, null);
// Access to the AdControl through the DOM
var adControl = template._value.childNodes[1].childNodes[1].winControl;
// Set options that are specified in the item
WinJS.UI.setOptions(adControl, { applicationId: item.AdAppId, adUnitId: item.AdUnitId });
return template;
}
else
{
return _$(".itemTemplate").winControl.render(item, null);
}
}
}

I had this problem in ratings:
<div data-win-control="WinJS.UI.Rating" data-win-options="{averageRating: 3.4, onchange: basics.changeRating}"></div>
I bind it via winControl:
<div data-win-control="WinJS.UI.Rating" data-win-bind="winControl.averageRating: myrating" data-win-options="{onchange: basics.changeRating}"></div>
It worked fine.

<div data-win-bind="this['data-list_item_index']:id WinJS.Binding.setAttribute" >

Related

In Razor Pages, how can I preserve the state of a checkbox which is not part of a form?

I have page that has checkbox that is used to expand/collapse some part of the page. This is client-side logic done in JavaScript.
I want to preserve the state of this checkbox for this particular page. Can Razor Pages do this automatically?
I tried by adding bool property with [BindProperty(SupportsGet = true)] in PageModel but it doesn't work - when I check the checkbox and reload (HTTP GET) the checkbox is always false.
Guessing that this toggle feature is user-specific, and that you want to persist their choice over a number of HTTP requests, I recommend setting a cookie using client-side code, which is user- or more accurately device-specific and can persist for as long as you need, and can be read on the server too.
https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie
https://www.learnrazorpages.com/razor-pages/cookies
I want to preserve the state of this checkbox for this particular page. Can Razor Pages do this automatically?
No, since you don't send it to the backend it will not show it.
As Mike said, it better we could store it inside the client cookie or storage.
More details, you could refer to below codes:
<p>
<input type="checkbox" id="cbox1" checked="checked">
<label >This is the first checkbox</label>
</p>
#section scripts{
<script>
$(function(){
var status = getValue();
if(status === "true"){
$("#cbox1").attr("checked","checked");
}else{
$("#cbox1").removeAttr("checked");
}
})
$("#cbox1").click(function(){
var re = $("#cbox1").is(":checked")
alert(re);
createItem(re);
});
function createItem(value) {
localStorage.setItem('status', value);
}
function getValue() {
return localStorage.getItem('status');
} // Gets the value of 'nameOfItem' and returns it
console.log(getValue()); //'value';
</script>
}

What is the most reliable way to fetching the scroped CSS attribute in vuejs?

In vuejs the elements are assigned an attribute starting 'data-v-***'
I could not find any docs about fetching this value so ended up using refs and grabbing the attributes of the main node:
<template>
<div class="m-colour-picker" ref="thisContainer">
...
</div>
</template>
const attributes = this.$refs.thisContainer.getAttributeNames();
let dataAttribute = '';
attributes.forEach((attribute: string) => {
if (attribute.substring(0, 5) === 'data-') {
dataAttribute = attribute;
}
});
But it feels a little forced.. is there a method in vue to fetch this already built in?
That has little to do with Vue.js. Data attributes for any element are automatically synced with it's internal dataset object.
Example:
console.log(foobar.dataset);
console.log(foobar.dataset.vFoo);
console.log(foobar.dataset.vBar);
// notice how data attributes containing more than the initial data- dash
// are automatically transformed to camel case:
// data-v-foo-bar ===> dataset.vFooBar
console.log(foobar.dataset.vFooBar);
// if all you care about is the names of the attributes:
console.log(Object.keys(foobar.dataset));
<div id="foobar" data-v-foo="bar" data-v-bar="baz" data-v-foo-bar="foobaz"></div>

Create a new binding context for a custom attribute

What I want
<div amazingattr.bind="foo">
${$someValueFromAmazingattr}
</div>
Just like how this works:
<div repeat.for="bar of bars">
${$index}
</div>
Where I got stuck
import {customAttribute} from "aurelia-framework";
#customAttribute("amazingattr")
export class AmazingattrCustomAttribute {
bind(binding, overrideContext) {
this.binding = binding;
}
valueChanged(newValue) {
this.binding.$someValueFromAmazingattr = newValue;
}
}
While this works, the $someValueFromAmazingattr is shared outside the custom attribute's element, so this doesn't work:
<div amazingattr.bind="foo">
Foo: ${$someValueFromAmazingattr}
</div>
<div amazingattr.bind="bar">
Bar: ${$someValueFromAmazingattr}
</div>
Both of the "Foo:" and the "Bar:" show the same last modified value, so either foo or bar changes, both binding change to that value.
Why I need this?
I'm working on a value animator, so while I cannot write this (because value converters cannot work this way):
${foo | animate:500 | numberFormat: "0.0"}
I could write something like this:
<template value-animator="value:foo;duration:500">
${$animatedValue | numberFormat: "0.0"}
</template>
I imagine I need to instruct aurelia to create a new binding context for the custom attribute, but I cannot find a way to do this. I looked into the repeat.for's implementation but that is so complicated, that I could figure it out. (also differs in that is creates multiple views, which I don't need)
After many many hours of searching, I came accross aurelia's with custom element and sort of reverse engineered the solution.
Disclaimer: This works, but I don't know if this is the correct way to do it. I did test this solution within embedded views (if.bind), did include parent properties, wrote parent properties, all seem to work, however some other binding solution also seem to work.
import {
BoundViewFactory,
ViewSlot,
customAttribute,
templateController,
createOverrideContext,
inject
} from "aurelia-framework";
#customAttribute("amazingattr")
#templateController //This instructs aurelia to give us control over the template inside this element
#inject(BoundViewFactory, ViewSlot) //Get the viewFactory for the underlying view and our viewSlot
export class AmazingattrCustomAttribute {
constructor(boundViewFactory, viewSlot) {
this.boundViewFactory = boundViewFactory;
this.viewSlot = viewSlot;
}
bind(binding, overrideContext) {
const myBindingContext = {
$someValueFromAmazingattr: this.value //Initial value
};
this.overrideContext = createOverrideContext(myBindingContext, overrideContext);
//Create our view, bind it to our new binding context and add it back to the DOM by using the viewSlot.
this.view = this.boundViewFactory.create();
this.view.bind(this.overrideContext.bindingContext, overrideContext);
this.viewSlot.add(this.view);
}
unbind() {
this.view.unbind(); //Cleanup
}
valueChanged(newValue) {
//`this.overrideContext.bindingContext` is the `myBindingContext` created at bind().
this.overrideContext.bindingContext.$someValueFromAmazingattr = newValue;
}
}

access object with dynamic variable vue.js

This is my object
var users ={
twitter : {
name : //,
lastname : //
},
facebook : {
name : //,
lastname : //
}
}
}
I have a dynamic variable activeuser that updates from Facebook to twitter.
What i'm trying to do is refer to the inner object in users depending on the value of activeuser. I need to give my div something like this class :
<div class=' {{users.activeuser}}'></div>
I know this is not how it should be done with vue.js. Do you have any suggestions?
Thank You!
Using VueJS you should be able to assign your dynamic variable to a Vue Model when you load the new object using a Vue setter $set('property name', 'value')
Example AJAX retreival:
$.getJSON('myURL.html?query=xxx', function(data, textStatus, jqXHR){
try{
MyVue.$set('dynamicObject', data);
}
catch(e){}
});
A generic Vue may look like this:
var MyVue = new Vue({
el:'#exampleDiv',
data: {
dynamicObject : ''
}
});
Bound to an example HTML element:
<div id="exampleDiv">
<label class="{{dynamicObject.activeuser}}">{{dynamicObject.username}}</label>
</div>
In the case that you have an object with an array of objects which also contain properties Vue makes it very simple to create many HTML elements (for each child object) by simply adding a v-repeat (example) to the desired HTML and assigning the datasource:
<div id="exampleDiv">
<label v-repeat="dynamicObject" class="{{dynamicObject.activeuser}}"></label>
</div>

Difference between dojoAttachpoint and id

<div dojoType="dojo.Dialog" id="alarmCatDialog" bgColor="#FFFFFF" bgOpacity="0.4" toggle="standard">
<div class='dijitInline'>
<input type='input' class='dateWidgetInput' dojoAttachPoint='numberOfDateNode' selected="true">
</div>
how to show this dialog I tried dijit.byId('alarmCatDialog').show();
The above code is a template and I called dijit.byId('alarmCatDialog').show() from the .js file .
dojo.attr(this.numberOfDateNode) this code works and I got the data .but if I change dojoattachpoint to id then I try dijit.byId('numberOfDateNode') will not work;
Your numberOfDateNode is a plain DOM node, not a widget/dijit, i.e. javascript object extending dijit/_Widget, which is the reason you cannot get a reference to it via dijit.byId("numberOfDateNode"). Use dojo.byId("numberOfDateNode") instead and you are all set.
dojoAttachPoint or its HTML5 valid version data-dojo-attach-point is being used inside a dijit template to attach a reference to DOM node or child dijit to dijit javascript object, which is the reason dijit.byId('alarmCatDialog').numberOfDateNode has a reference to your <input type='input' class='dateWidgetInput' .../>.
The main reason to use data-dojo-attach-point is that:
you can create multiple instances of dijit and therefore your template cannot identify nodes/dijits by IDs as you will have multiple nodes/dijits with the same ID
it's an elegant declarative way, so your code won't be full of dijit.byId/dojo.byId.
It is important to keep track of what is the contents and which is the template of the dijit.Dialog. Once you set contents of a dialog, its markup is parsed - but not in a manner, such that the TemplatedMixin is applied to the content-markup-declared-widgets.
To successfully implement a template, you would need something similar to the following code, note that I've commented where attachPoints kicks in.
This SitePen blog renders nice info on the subject
define(
[
"dojo/declare",
"dojo/_base/lang",
"dijit/_Templated",
"dijit/_Widget",
"dijit/Dialog"
], function(
declare,
lang,
_Templated,
_Widget,
Dialog
) {
return declare("my.Dialog", [Dialog, _Templated], {
// set any widget (Dialog construct) default parameters here
toggle: 'standard',
// render the dijit over a specific template
// you should be aware, that once this templateString is overloaded,
// then the one within Dialog is not rendered
templateString: '<div bgColor="#FFFFFF" bgOpacity="0.4">' +// our domNode reference
'<div class="dijitInline">' +
// setting a dojoAttachPoint makes it referencable from within widget by this attribute's value
' <input type="input" class="dateWidgetInput" dojoAttachPoint="numberOfDateNode" selected="true">' +
'</div>' +
'</div>',
constructor: function(args, srcNodeRef) {
args = args || {} // assert, we must mixin minimum an empty object
lang.mixin(this, args);
},
postCreate: function() {
// with most overrides, preferred way is to call super functionality first
this.inherited(arguments);
// here we can manipulate the contents of our widget,
// template parser _has run from this point forward
var input = this.numberOfDateNode;
// say we want to perform something on the numberOfDateNode, do so
},
// say we want to use dojo.Stateful pattern such that a call like
// myDialogInstance.set("dateValue", 1234)
// will automatically set the input.value, do as follows
_setDateValueAttr: function(val) {
// NB: USING dojoAttachPoint REFERENCE
this.numberOfDateNode.value = val;
},
// and in turn we must set up the getter
_getDateValueAttr: function() {
// NB: USING dojoAttachPoint REFERENCE
return this.numberOfDateNode.value;
}
});
});