How to disable content based on checkbox in AngularJS/Bootstrap3 - angularjs

I am creating a form where the user can configure a recurring event, so there are a large number of controls. At the top is a checkbox to enable/disable the schedule.
How can I disable, but not hide, the entire section based on the checkbox? If it is checked, the user should be able to make modifications to the schedule. If it is not checked, no changes should be allowed.
I'm fairly certain I can use the ng-disabled directive on each control, but I'd like to set some attribute/class on the entire container, rather than on each individual control.
I am using Bootstrap 3, so if there is a class that would provide this functionality, that would be an acceptable solution as well.
Here is the relevant section of the HTML:
<input type="checkbox" ng-model="status" title="Enable/Disable Schedule" /> <b>Schedule the task to run:</b>
<div class="row"> <!-- need a way to disable this row based on the checkbox -->
<span>Every <input type="number" ng-model="interval" />
<select ng-model="frequency"
ng-options="freq as freq.name for freq in frequencies"></select>
</span>
<div>
On these days:
</div>
<div class="btn-group" data-toggle="buttons-checkbox">
<button type="button"
class="btn"
ng-model="day.value"
ng-repeat="day in days">{{day.name}}</button>
</div>
</div>
I have tried:
<div class="row" ng-disabled="!status">
It didn't work, and based on the docs, it doesn't look like it is even supposed to, as its intended use is for disabling form controls. I also tried without the !, just to validate that it wouldn't work either.

OK, I found a technique that works for my purposes...
<div class="row" ng-class="{disabled: !status}"> <!-- added ng-class here -->
and
.disabled {
z-index: 1000;
background-color: lightgrey;
opacity: 0.6;
pointer-events: none;
}
This prevents clicks on the page and gives a nice visual indication of the section being "disabled".
It does not prevent me from tabbing through the controls, but it works OK for my purposes.

Related

cy.get div that hasn't got a display: none on it

I'm working on some poor code, that someone else has written. I'm trying to write some tests for the functionality, before we're changing it, so we can ensure it all works, after the feature-changes.
I have 8 siblings divs like this:
<div class="container">
<!-- Child-1 -->
<div class="child-group child-1" style=""> <!-- Notice empty style-tag -->
<div class="buttons">
<button class="go-to-child-group-1">Child-group-1</button>
<button class="go-to-child-group-2">Child-group-2</button>
<button class="go-to-child-group-3">Child-group-3</button>
... <!-- Leaving out all the buttons for readability -->
<button class="go-to-child-group-8">Child-group-8</button>
</div>
<div class="content">Content1 content1 content1</div>
</div>
<!-- Child-2 -->
<div class="child-group child-2" style="display: none"> <!-- Notice display none -->
<div class="buttons">
<button class="go-to-child-group-1">Child-group-1</button>
<button class="go-to-child-group-2">Child-group-2</button>
<button class="go-to-child-group-3">Child-group-3</button>
... <!-- Leaving out all the buttons for readability -->
<button class="go-to-child-group-8">Child-group-8</button>
</div>
<div class="content">Content2 content2 content2</div>
</div>
<!-- Child-3 -->
<div class="child-group child-3" style="display: none"> <!-- Notice display none -->
<div class="buttons">
<button class="go-to-child-group-1">Child-group-1</button>
<button class="go-to-child-group-2">Child-group-2</button>
<button class="go-to-child-group-3">Child-group-3</button>
... <!-- Leaving out all the buttons for readability -->
<button class="go-to-child-group-8">Child-group-8</button>
</div>
<div class="content">Content3 content3 content3</div>
</div>
<!--
Etc. etc. etc.
for group Child-4, Child-5, Child-6, Child-7 and Child-8
-->
</div>
When you click one of the buttons, it sets display: none on the active group - and removes display: none from the child-group that needs to become visible.
I'm trying to write a test, that first activates a certain child-group (by clicking the the button to make it visible) and afterwards checks the content is correct.
But when I do this:
cy.get( ".child-group .buttons .go-to-child-group-2" ).click();
Then my test fails with this error:
cy.click() can only be called on a single element. Your subject contained 8 elements. Pass { multiple: true } if you want to serially click each element.
It's obviously crap, that all the buttons are loaded on each element. But we can't change that until further down the line.
How do I select only the .child-group that doesn't have display: none set on it?
Solution attempt 1: Select by style
I found this post on how to select by style. But since I'm trying to select the one without the style, that makes this more difficult.
I tried this:
cy.get( ".child-group[style*='display: block'] .buttons .go-to-child-group-2" ).click();
But that doesn't work. And when I inspect the element without the display: none, then I can find no display-style on it. And I could also read that display didn't have any default value.
Solution attempt 2: Make cy.get(...) disregard all non-visible elements.
I found a bit about Interacting with Elements, but it didn't tell me how I could pass that option the my cy.get-function.
I also checked the documentation for cy.get, but couldn't find anything either.
Solution attempt 3: Simply click all the buttons (poor)
I could do what it says and click all the buttons, by calling the click-function like this:
cy.get( ".child-group .buttons .go-to-child-group-2" ).click( {multiple: true, force: true});
This works, but I was hoping for a better solution.
I think you're looking for the :not() pseudo selector
cy.get('.child-group .buttons .go-to-child-group-2:not([style="display: none"])')
I guess it's also worth trying this, but not sure if the empty string will throw it
cy.get('.child-group .buttons .go-to-child-group-2[style=""]')
Alternatively, you can use the :visible selector.
cy.get('.child-group .buttons .go-to-child-group-2')
.filter(':visible') // filter only visible elements
Here is a simple example

Lightning-combobox getting cut off

I am building a lightning web component that uses a combobox. It seems to be having its dropdown portion cut short by the bounds of its container.
I've tried adding height, z-index, overflow, and margin modifiers to the style sheet for the input element and its container, and the only thing that's had a visible effect is adding margin to the combobox's container, which just makes more space for the dropdown to show its contents but doesn't solve the problem.
Here is an excerpt of the html file:
<div class="slds-col slds-grid">
<!-- Complete Task -->
<div class="slds-grid slds-col slds-size_2-of-4 slds-p-right_small slds-truncate">
<div class="slds-col">
<div class="slds-border_bottom" style="background-color: #ecd4b566">Log a Call</div>
<div class="slds-grid_vertical slds-p-top_small">
<div class="slds-col">
<lightning-combobox
class="spencer_combobox"
variant="label-hidden"
placeholder="-- Call Result --"
options={callResults}
value={selectedResult}
required
onchange={handleResultSelection}>
</lightning-combobox>
</div>
<div class="slds-col">
<lightning-textarea maxlength=255 placeholder="Write comments here" onchange={handleComment} value={commentValue}></lightning-textarea>
</div>
<div class="slds-col">
<lightning-button class="slds-col" variant="Brand" label="Complete Task" onclick={handleCompleteTaskClick} disabled={buttonDisabled}></lightning-button>
</div>
</div>
</div>
</div>
I expected the dropdown to be visible on top of the other elements, but it ends up hidden or cut off.
Here is a screenshot; the dropdown menu isn't being cut off by the next element below it, it's actually getting cut off by its own bounds.
Figured it out.
I put slds-truncate in the class of the container, and that comes with overflow:hidden, so I was able to just remove the truncate or edit the style sheet to fix the problem.

Ng-class not working in Popup template Ionic. What am I doing wrong?

I've been tinkering around a bit with AngularJS and the Ionic framework. Now I would like to display 12 buttons inside a popup. I have this all working, but I would like the buttons to switch appearance when they got pressed.
html
<label>
<p>Fill in catergory name</p>
<input type="text" placeholder="Rent">
</label>
<br />
<br />
<div class="row">
<div class="col col-25"><button class="button button-outline" id="button12in" ng-class="button12 ? 'button12in' : 'button12inpress'" ng-click="button12 = !button12">
</div>
</div>
As you can see I've been trying with button 12.
app.js
$scope.button12 = false;
css
#button12in {background-color: #51FF00;}
#button12inpress{border-style: solid; border-color: black; border-width: 4px;background-color: #51FF00;}
So the idea is that clicking on the button will change the state of $scope.button12. The result of this would be that via the ng-class the button will change style! but for some reason, this is not possible. It picks up the changed state of button12 but the ng-class isn't working in all kinds of syntax I've tried
I think it should be
ng-class="{'class': trueOrFalse}"
To apply different classes when different expressions evaluate to true:
<div ng-class="{class1 : expression1, class2 : expression2}">
Hello World!
</div>
To apply multiple classes when an expression holds true:
<!-- notice expression1 used twice -->
<div ng-class="{class1 : expression1, class2 : expression1}">
Hello World!
</div>
or quite simply:
<div ng-class="{'class1 class2' : expression1}">
Hello World!
</div>
Notice the single quotes surrounding css classes.
or check this Adding multiple class using ng-class
Don't use your flag directly on $scope , but rather try setting the flag on an object on $scope
Example
Use $scope.flagContainer.button12 instead of $scope.button12
$scope.flagContainer = {
button12 : false
}
Now change it view accordingly

Dropdown item text in AngularJS, bootstrap gets chopped from bottom

My dropdown has several values, when clicks on dropdown to see the list, grey has full 'y'. Upon selection, bottom portion of Grey gets chopped. This is happening with all similar characters.
Edit:
<div class="col-lg-6"><div class="col-lg-6">
<div class="form-group" ng-repeat="attrib in col1Attribs">
<div ng-class="invalidCodeClass">
<label class="control-label" for="txtCode">{{attrib.displayText}}</label>
<select id="ddl{{attrib.configType}}" class="form-control">
<option ng-repeat="c in configOptions(attrib.configType)" value="{{c.configId}}">{{c.configValue}}</option>
</select>
</div>
</div>
</div>
I don't think the problem is in your html or js code but rather with the css applied by the particular browser with which you are viewing the page.
Try changing the (font) styling on the select list; some suggestions:
1. reducing font size
2. increase line-height on select
3. removing styling options on select as #yuujin has suggested.
Probably with one of those changes you will be able to resolve the issue.

Using a Conditional Statement in AngularUI's Collapse Directive

Can I place a conditional statement into the collapse directive for AngularUI?
I have the following setup, which has 3 radio-style buttons:
<div class="controls controls-row">
<div class="btn-group" data-toggle="buttons-radio">
<button type="button" class="btn" ng-model="radioPurpose" btn-radio="'meeting'">Meeting</button>
<button type="button" class="btn" ng-model="radioPurpose" btn-radio="'tour'">Tour</button>
<button type="button" class="btn" ng-model="radioPurpose" btn-radio="'other'">Other...</button>
</div>
</div>
<div class="controls controls-row">
<textarea class="span6" placeholder="Why are you here?" ng-model="textPurpose" collapse="{{ radioPurpose == 'other' }}"></textarea>
</div>
I would like textarea to show/hide according to the value of the radioPurpose buttons. I know the statement is evaluating to true at the appropriate time, but the directive always shows the textarea.
Copied answer from comment:
I haven't used AngularUI, but I'm guessing collapse expects an expression. Remove the curly braces: collapse="radioPurpose == 'other'"
Collapse is actually not the best way of doing a simple show/hide. A collapsed item has its height set to 0, rather than being set to display: none; it might not always have the effect you're expecting. I would suggest instead using ng-show or ng-hide.
http://docs.angularjs.org/api/ng.directive:ngShow
I saw that you solved it, and so did I and can share my JSFiddle; Toggle Collapse with Radiobuttons.
However, I see what S McCrohan mean, since I got a problem in my app. The collapse for the table did not work fully in my app first, since it collapsed but left the top row visible. It seems to require that you separate the divs, i.e. a div with collapse and a div with span# class, like following...:
<!-- START CHART AREA -->
<div collapse="chartCollapsed">
<div class="span12 well well-small">
<div id="chart_div" style="width: 600px; height: 400px;"></div>
</div>
</div>
<!-- END CHART AREA -->
<!-- START TABLE AREA -->
<div collapse="tableCollapsed">
<div class="span12">
<!-- TABLE OMITTED -->
</div>
</div>
<!-- END TABLE AREA -->

Resources