I'm trying to disable or enable a button based on checkboxes. if two more are checked the button is no longer disabled. This part works but I'm not sure how to disable the buttons again if I uncheck items.
i'm new to vue but I'm wondering how to find out if each checkbox has been either checked OR unchecked so I can correctly move my counter up or down.
<li class="listItemsModal" v-for="(student, index) in students">
<input v-model="student.exclude" #change="toggleAddButton" id="student.index" type="checkbox" >
{{student.first_name}}
</li>
if the button is clicked we add and check to see if the value is bigger than 2
I need some way to access the checked value to see if checked or not, then go up or down accordingly
toggleAddButton: function(){
console.log(this.studentsAdded)
this.studentsAdded ++
if(this.studentsAdded >= 2){
this.disableAdd = false
}else{
this.disableAdd = true
}
}
There are a bunch of ways to do this, some are easier or harder depending on your data structures.
If your students array is fully reactive you could have a computed property that updates any time that object changes. Something like:
// ... vue stuff...
computed:{
// ... your other computed properties
enoughBoxesChecked(){
// you could also use an accumulator, but this is very easy to read.
return this.students.filter(student=>student.exclude).length > 2;
}
}
// ... other vue stuff
Then you could use that enoughBoxesChecked computed property on the button you want to disable. Something like <button :disabled="enoughBoxesChecked">....
Related
I have a span which should have an onclick attribute if the IsActive bool is true.
Otherwise the span should have no onclick attribute.
e.g.
#if (IsActive == true)
{
<span #onclick="#(e => Go.DoSomething("please"))">
#s.DisplayText
</span>
}
else
{
<span>
#s.DisplayText
</span>
}
Is there not a way to avoid the repeated code using a ternary operator? e.g.
#(IsActive == true ? "add onclick method somehow?" : "")
A better way to add the condition IsActive == true is in the Go.DoSomething method. But ideally I would have used a button if its clickable because we can add a disabled attribute to a button, in your case you can add the condition inside the onclick method.
Just a tip for the button, you can just add your c# boolean property within that attribute like this:
<button disabled="#IsActive">Save</button>
You can do the following.
<span #onclick="#(e => { if (IsActive) Go.DoSomething("please");})">
#s
</span>
A Lambda Expression is what I think you are really looking for.
Just want to add something for people having a similar problem:
If you have more HTML code than a single span and you would need it twice because of an if-else-statement, I would create a own Blazor component (e.g. MyComponent.razor) and use component parameters.
This way you donĀ“t have much duplicate code in an if-else-statement.
Other answers are kind of wrong. There is a difference between registering an event method as a lambda and not registering an event if not necessary.
If you move the condition to a lambda function, anytime someone click your method will run. It would have a performance impact on your app, especially if it is Blazor Server since the round trip has to happen and the logic happens on your server.
#ondclick=#(Active?() => Go.DoSomething:null)
will not register the event if it is not active so no load on your server.
from Blazor Repository Tests
I'm building a list of v-checkboxes using this code
<div class="row form-group" v-for="(author, key) in authorData" :key="key">
<v-layout row wrap>
<v-flex xs1 sm1 md1 text-xs-center>
<div>
<v-checkbox
label
:key="author.PmPubsAuthorID"
v-model="authorData[key].checked"
v-bind:id="author.PmPubsAuthorID.toString()"
color="success"
#change="authorCBClicked(authorData[key])"
></v-checkbox>
</div>
The PmPubsAuthorID is a number like 1047602 and is a sequential number in the entire database, no 2 records are the same. When I run the code to build the list it works fine and shows a checkbox if the value is true. What I am trying to do is when a checkbox is checked in the
authorCBClicked(author) {
//PmPubsAuthorID = 1047602
// alert(author.PmPubsAuthorID + " " );
// author.checked = false; does not work
this.authorData[author.PmPubsAuthorID].checked = false; does not work
this.authorData["1047602"].checked = false; does not work
this.authorData[1047602].checked = false; does not work
this.authorData[2].checked = false; does work
},
As you can see I have tried various ideas and the only one that seems to work is passing in an ordinal but I have no way of knowing that. Do I need to use an index when building the checkboxes?
The reason: I have a checkbox then when checked calls a dialog box that asks " Are you sure you want to "Add this item to the list" if they say yes I want the original checkbox to be checked but if they say no then the original checkbox needs to be false. I have found that if I try to set the checked status of the calling checkbox to false it does not work but works fine once outside that method. I have passed the key and author information to the new dialog and let it change the checkbox to false if needed
Thanks for the help.
Just pass the key instead of the whole item to your method :
#change="authorCBClicked(key)"
and on your method :
authorCBClicked(key) {
this.authorData[key].checked = !this.authorData[key].checked;
}
Or :
you can do it directly on the template :
#change="author.checked = !author.checked"
I have a simple dom-if in a template:
<div>
<template is="dom-if" if="{{checkListEmpty()}}" restamp>
<paper-button raised class="init" on-tap="initialize">Initialize</paper-button>
</template>
</div>
and a function to show or hide.
checkListEmpty() {
return this.todos.length == 0;
}
It works for the first time only. If the this.todos.length becomes 1 then the template does not goes away. How can i hide when the condition is false.
There is no binding working for your function because there is no property to bind.
To make it work you should add a property in parameter : checkListEmpty(foo).
Like that, everytime the property foo change the function will be executed.
However an array as property won't work if the content of this one changed (content pushed) except if this is the global array property that is replaced :
var bar = [], foo = ["ggg"];
bar = foo;
In that case the function will be called, but it's not great.
Anyway for your question you can use an hidden property for the paper-button or bind the DOM-IF with the table length.
<template is="dom-if" if="[[!bar.length]]" restamp>
<paper-button raised on-tap="addBar">Initialize</paper-button>
</template>
or
<paper-button raised on-tap="addBar" hidden="[[bar.length]]">Initialize</paper-button>
And then everytime a property is added into the array or removed until there is nothing in it your button will be displayed or not.
You can see a working jsfiddle (use chrome though and be patient for the initialization.. comment here if it's not working)
I am trying to have a checkbox inside a button and both clicking on the checkbox or the button should toggle the checkbox and the boolean value bound to it from the view model.
app.html:
<template>
<h1>${heading}</h1>
<button type="button" click.trigger="toggleIsChecked()">
<input type="checkbox" checked.bind="isChecked"> ${isChecked}
</button>
</template>
app.ts:
export class App {
isChecked: boolean;
toggleIsChecked() {
this.isChecked = !this.isChecked;
}
}
What happens is that when I click the button (outside the checkbox) everything works as expected. But when I click the checkbox the boolean value in the view model changes but the checkbox is not checked or unchecked. What could be causing this?
I have tried different approaches but they all produce similar results. While debugging I noticed the checkbox gets checked but something in the Aurelia framework removes it almost instantly. Seems like the event handling is not working properly?
EDIT: I made a gist so you can try it yourself: https://gist.run/?id=4a7b2c11db33bdb37213eb4ea1b5b2b0
It's not the Aurelia framework that is "removing" the checking. What is happening is that when you click the checkbox, the isChecked is automatically set to true, then toggleIsChecked() is fired and isChecked is set to false (isChecked is set twice when you click the checkbox). To solve this you have to not set isChecked if the target is the checkbox. Something like this:
JS
toggleIsChecked(event) {
if (event.target.tagName === 'INPUT') {
return true; //checkbox has been clicked, do nothing!
}
this.isChecked = !this.isChecked;
}
HTML
<button type="button" click.trigger="toggleIsChecked($event)">
<input type="checkbox" checked.bind="isChecked"> ${isChecked}
</button>
Same explanation with Fabio Luz & going to do the same thing, but instead of checking event target tag name, You can use self binding behavior, like this
<template>
<require from='./self'></require>
<h1>${heading}</h1>
<button type="button" click.delegate="toggleIsChecked() & self">
<input type="checkbox" checked.bind="isChecked"> ${isChecked}
</button>
</template>
What self binding behavior does here is to ensure toggleIsChecked only fires when you click on button itself, not its descendant, same with this block of code:
toggleIsChecked(event) {
if (event.target === this.button) {
// Do your thing
}
}
Note: self just got merged, but has not been released yet. I have included the code at this gist: https://gist.run/?id=5e66dfd996d852344a524010ae82a936
You can read more about the PR here: https://github.com/aurelia/templating-resources/pull/263
Kind people at the Aurelia Gitter chat provided me with an answer. What is happening in my gist is that the default event handler is not being called. Reason for this is that Aurelia automatically calls the event.preventDefault() function. In order for the default event handler to be called I must return true from my own event handler. Here's a working gist proving how it works: https://gist.run/?id=3cb545572065cffd737f98788a4105a1
Thank you all for your answers. I decided to answer this myself since I got the answer from the Gitter chat, but the kudos belongs to the awesome Aurelia community and especially #CasiOo.
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 :)