I have a Windows 8 app with a template that contains a div I want to show or hide based on the value of a property inside a data-win-control="WinJS.Binding.Template". I have tried the following without luck:
<div data-win-bind="visible: isMore"> ..content... </div>
where isMore is a boolean property of the databound item.
How can I do that? I guess the visible property does not exist?
You are right - the visible property doesn't exist, but you can control the appearance using CSS and a binding converter.
First, use WinJS.Binding.converter to create a converter function that translates a boolean to a value value for the CSS display property, like this:
var myConverter = WinJS.Binding.converter(function (val) {
return val ? "block" : "none";
});
Make sure that the function is globally available - I use WinJS.Namespace.define to create collections of these converters that I can get to globally.
Now you can use the converter in your data binding to control the CSS display property, like this:
<div data-win-bind="style.display: isMore myConverter"> ..content... </div>
Related
I am writing my first app in Vue3 and I use composition-api with script setup.
Using v-for, I create components that are inputs (CrosswordTile) that make up the crossword grid.
A problem appeared during the implementation of the field containing a clue to the password.
Since the text doesn't allow text to wrap, I wanted to dynamically change the tag to after a click.
Function in parent component where I handle logic after click that change tile type works fine, but I need to change tag of "target" to and set maxLength to a different value.
If it would help here is whole code on github: https://github.com/shadowas-py/lang-cross/tree/question-tile, inside CrosswordGrid.vue.
function handleTileTypeChange(target: HTMLInputElement) {
if (target && !target.classList.contains('question-field')) {
addStyle(target, ['question-field']);
iterateCrosswordTiles(getNextTile.value(target), removeStyle, ['selected-to-word-search', 'direction-marking-tile']);
} else if (target) {
removeStyle(target, ['question-field']);
if (getPrevTile.value(target)?.classList.contains('direction-marking-tile')) {
iterateCrosswordTiles(
target,
addStyle,
['selected-to-word-search', 'direction-marking-tile'],
);
}
}
TEMPLATE of ParentComponent
<div
class="csw-grid"
#input="handleKeyboardEvent($event as any)"
#mousedown.left.stop="handleClickEvent($event)"
#click.stop="">
<div v-for="row in 10" :key="row" class="csw-row" :id="`csw-row-${row}`">
<CrosswordTile
v-for="col in 8"
:key="`${col}-${row}`"
#click.right.prevent='handleTileTypeChange($event.target)'
/>
</div>
</div>
I tried to use v-if inside CrosswordTile, but it creates a new element, but I just need to modify the original one (to add/remove HTML classes from it basing on logic inside CrosswordGrid component).
How can I get access to the current component instance properties when using the composition API in script setup or how to replace the tag dynamically?
:is and is doesn't work at all.
I am using Vue 2 and I am using an anchor tag as a "button" (for styling purposes with an svg).
The drawback of using an anchor tag in this way is that you can't disable it in the same way as a button.
I would like to make a vue component that simply wraps an anchor tag. I would like the component to pass all properties of the custom component onto the child anchor tag so that someone can use it like this:
<custom-comp id="closeButton" title="Close" class="c-btn" #click="close" :disable="true"></custom-comp>
I want to intercept the click on the child anchor tag and only emit that if the component is not disabled.
How can I achieve this?
You can't. disable property is used only in form elements. What you're looking for here is to use v-if:
<a id="closeButton" title="Close" class="c-btn" #click="close" v-if="isConditionMatched">
Only show if isConditionMatched returns true
</a>
Or, conditionally you can use return false statement inside your method:
close() {
if(!isConditionMatched) return false;
// continue your close function
}
Using can 2.2 : I'm having trouble getting a radio input field to be checked by default when also using the can-value attribute.
The relevant part of the stache template looks like this:
<input type="radio" name="visibility" value="corporate" can-value="reportData.visibility" checked="checked"/>
The relevant part of my viewModel looks like this:
can.Map.extend({
reportData = {
visibility: 'corporate',
}
});
I want the input value to be live-bound to my view model. According to the can 2.2 docs, I can use the can-value attribute on an input to reference a property on my view model and keep it in sync with the value of the input's value. My problem is the checked="checked" doesn't result in the input being checked by default, though the value on the input item (corporate) is being correctly live-bound. If I remove the can-value attribute, the check appears by default. How can I get both live-binding and a checked input by default with the help of can-value?
I want to show a popup dialog containing a dijit.ComboBox with data populated using ajax request or data store.
The problem I am facing is that the combobox is always disabled.
My selected code is:
<div dojoType="dojo.data.ItemFileReadStore" id="osTypeStore" data-dojo-id="osTypeStore" url="/AjaxPopulateOS.json">
</div>
<select id="osType" data-dojo-type="dijit.form.ComboBox"
data-dojo-props="
id:'osType',
store: osTypeStore,
placeHolder: 'Select a schdule type'" >
</select>
Any ideas
I believe it is because there are no items in it? Is it grayed out totally - and have the Disabled class parameter set?
Check that dijit.byId('osTypeStore') returns a store and that it has items in it.
If this is the case, change your code to
store: 'osTypeStore'
Note the quotes. This forces parser to evaluate the string into a dijit - and the store might not have been initialized correctly as a true variable at the point it is read. In other words, in combobox constructor - the javascript variable is undefined.
If this does not help, try forcing to set store after onShow has run for your dialog.
dialog.onShow = function() {
dijit.byId('osType').set('store', dijit.byId('osTypeStore'));
}
Try forcing it to enabled using the property of the combo
enabled: true,
Other than that, check it using Firebug or debug bar or something similar :)
Is there any way to disable all input fields in an div container with dojo?
Something like:
dijit.byId('main').disable -> Input
That's how I do it:
dojo.query("input, button, textarea, select", container).attr("disabled", true);
This one-liner disables all form elements in the given container.
Sure there is. Open up this form test page for example, launch FireBug and execute in the console:
var container = dojo.query('div')[13];
console.log(container);
dojo.query('input', container).forEach(
function(inputElem){
console.log(inputElem);
inputElem.disabled = 'disabled';
}
)
Notes:
On that test page form elements are actually dijit form widgets, but in this sample I'm treating them as if they were normal input tags
The second dojo.query selects all input elements within the container element. If the container had some unique id, you could simplify the sample by having only one dojo.query: dojo.query('#containerId input').forEach( ...
forEach loops through all found input elements and applies the given function on them.
Update: There's also a shortcut for setting an attribute value using NodeList's attr function instead of forEach. attr takes first the attribute name and then the value or an object with name/value pairs:
var container = dojo.query('div')[13];
dojo.query('input', container).attr('disabled', 'disabled');
Something else to keep in mind is the difference between A Dijit and a regular DomNode. If you want all Dijit's within a DomNode, you can convert them from Nodes -> Dijit refs with query no problem:
// find all widget-dom-nodes in a div, convert them to dijit reference:
var widgets = dojo.query("[widgetId]", someDiv).map(dijit.byNode);
// now iterate over that array making each disabled in dijit-land:
dojo.forEach(widgets, function(w){ w.attr("disabled", "disabled"); }
It really just depends on if your inputs are regular Dom input tags or have been converted into the rich Dijit templates (which all do have a regular input within them, just controlled by the widget reference instead)
I would do it like this:
var widgets;
require(["dijit/registry", "dojo/dom"], function(registry, dom){
widgets = registry.findWidgets(dom.byId(domId));
});
require(["dojo/_base/array"], function(array){
array.forEach(widgets, function(widget, index) {
widget.set("disabled", true);
});
});
Method findWidgets is essential to get all widgets underneath a specific DOM.