How do I use Watir to select the options of an Angular powered bootstrap dropdown list? - angularjs

The code is
<div _ngcontent-pvu-c241="" class="col-sm-6 col-md-4 col-lg-3">
<ng-select _ngcontent-pvu-c241="" name="customer_invitation_status" class="form-ng-select ng-select-clearable ng-select ng-select-single ng-pristine ng-valid ng-touched ng-select-bottom">
<div class="ng-select-container">
<div class="ng-value-container">
<div class="ng-placeholder">Customer Invitation</div>
<!----><!---->
<div role="combobox" aria-haspopup="listbox" class="ng-input" aria-expanded="false"><input aria-autocomplete="list" type="text" autocorrect="off" autocapitalize="off" autocomplete="a19ee7afde6a" readonly=""></div>
</div>
<!----><!----><span class="ng-arrow-wrapper"><span class="ng-arrow"></span></span>
</div>
<!---->
</ng-select>
</div>
When a person clicks on the div with a role of combobox, it adds this to the above HTML in addition to adding some cosmetic classes as well.
<ng-dropdown-panel role="listbox" aria-label="Options list" class="ng-dropdown-panel ng-select-bottom" id="a19ee7afde6a" style="opacity: 1;">
<!---->
<div class="ng-dropdown-panel-items scroll-host">
<div></div>
<div>
<div class="ng-option ng-option-marked" role="option" aria-selected="false" id="a19ee7afde6a-0">
<!----><span class="ng-option-label">Reservation Sent</span><!---->
</div>
<div class="ng-option" role="option" aria-selected="false" id="a19ee7afde6a-1">
<!----><span class="ng-option-label">Reservation Not Sent</span><!---->
</div>
<!----><!----><!----><!----><!----><!---->
</div>
</div>
<!---->
</ng-dropdown-panel>
I noticed that using .click! does absolutely nothing, but using
execute_script("arguments[0].click(), dropdown)
where dropdown can be obtained by grabbing the element with the name 'customer_invitation_status' or the element with the text 'Customer Invitation' inside of it.
DOES do something, but only after the Watir script crashes (The click happens after the script ends as opposed to during). While it's running, I'm not able to find the new elements: aka the span/element with the text, 'Reservation Not Sent' or ID of 'a19ee7afde6a-1' that should show up as as result of the click.
After the script crashes due to not being able to click on the span with the text 'Reservation Not Sent' because it doesn't exist, the click happens.

Related

How can I have two ng-contents in the same template controlled by *ngIf

I have an angular 2 component for displaying a bootstrap 3 button group. The component can either have a label or it can stand alone.
My solution was to use two ng-contents controlled by an *ngIf however, it refuses to display either of the ng-contents and does not throw an error.
Here's btn-multi.html:
<div class="form-group"
*ngIf="label">
<label class="control-label col-lg-2 col-md-3">
{{ label }}
</label>
<div class="col-lg-10 col-md-9">
<div class="btn-group">
<ng-content></ng-content>
</div>
</div>
</div>
<div class="btn-group"
*ngIf="!label">
<ng-content></ng-content>
</div>
And here is how it is used:
<btn-multi label="Some Label"
[(value)]="someValue">
<btn [value]="true">Yes</btn>
<btn [value]="false">No</btn>
</btn-multi>
And this is it working with just the one ng-content:
I'm currently on angular 2 beta-15.
Thanks!
NgIf is getting in the way of including the content since ng-content is being rendered after NgIf is evaluated.
You need to take another approach on it, maybe something like this:
<div [ngClass]="{'form-group': label}">
<label *ngIf="label" class="control-label col-lg-2 col-md-3">
{{ label }}
</label>
<div [ngClass]="{'col-lg-10 col-md-9': label}">
<div class="btn-group">
<ng-content></ng-content>
</div>
</div>
</div>
And there are also even better ways to do it, it all depends on how you want this component to be consumed.
FYI, just did this on the fly so its not tested, but just to give you a general idea.

Unable to update a given item in an array from Angularjs controller

I am having a requirement to create a search query of parameters and send it to server. I have created the drop downs from where the user will populate the values. Below is the code on the UI:
<div ng-repeat="criteria in criterias">
<div class="m-b">
<div class="form-group s-b" style="width: 150px;">
<span>classification</span>
<select ng-model="criteria.selectedClassification" class="form-control" id="classification" ng-options="classification for classification in classification" ng-change="handleClassification(criteria)" style="max-width:100%"></select>
</div>
<div class="form-group s-b" style="width: 150px;">
<span>Config</span>
<select id="config" ng-model="criteria.selectedConfig" ng-options="config for config in config" class="form-control" ng-change="handleConfig(criteria)" style="max-width:100%" ></select>
</div>
<div class="form-group s-b" style="width: 150px;">
<span>Attribute</span>
<select id="attribute" class="form-control" ng-options="attribute for attribute in attributes" ng-model="criteria.selectedAttribute" style="max-width:100%;" ng-change="handleAttrChange(criteria )"></select>
</div>
<div class="form-group s-b" style="width: 150px;">
<span>Predicate</span>
<select class="form-control" ng-model="criteria.predicate" style="max-width:100%">
<option value="matches">Matches</option>
<option value="not-matches">Not Matches</option>
</select>
</div>
<div class="form-group s-b" style="width: 100px;">
<span>Value</span>
<select class="form-control" name="account" ng-model="criteria.value" ng-options="item for item in values" style="max-width:100%">
</select>
</div>
<div class="form-group s-b" style="margin-top: 20px;">
<span>
<button class="btn btn-sm btn-primary pad-btn" type="submit" ng-click="addCriteria()"><i class="fa fa-plus"></i>
</button>
<button class="btn btn-sm btn-danger pad-btn" type="submit" ng-click="deleteCriteria(criteria)"><i
class="fa fa-minus"></i></button>
</span>
</div>
</div>
</div>
I have wrapped the code inside a repeat so that the user can create multiple criteria (each having one filter condition). The user can create criteria by clicking on the + icon. I am facing issues when working with one criteria, any update done on the config is setting the attributes of all the criteia instead of the current criteria.
I have created a working plunker to demo this. Please let me know where I am going wrong.
Link to Plunker - Link to Plunker
The issue is your list of attributes.
Whenever you are changing the config, you are calling a function that is changing the list of attributes. Each row of criteria is looking at the same attributes array. So if you change the config in the first and the third row, they are both affecting what attributes is set to, so it's filtering the array twice.
To avoid this, each of your rows should have an array of the lookups you're going to be filtering on. Then inside the function of the ng-change, filter the array that is in your current criteria, so that each row of criteria is using it's own lookup.

How to add plus minus symbol to a bootstrap accordion along with angularjs

I am using bootstrap accordion in angular js. The panels are opening If I click on the heading directly but I need to add plus/minus symbols for each heading. Please help me out in achieving the functionality like If I click plus icon, panel should be open and If I click on minus symbol, the panel should be closed. Thanks in advance.
Sorry, I Cannot able to add fiddle or plunker as the data is coming from my local database.
<uib-accordion close-others="oneAtATime" class="accordion-data">
<uib-accordion-group heading="title from database" ng-repeat="values are coming from database">
<div class="row">
<div class="col-md-12">
<div class="row row-head">
<div class="col-md-6 col-xs-6">
</div>
</div>
<div class="row item-head accordion-content" ng-repeat="values are coming from database">
<div class="col-md-4 col-xs-4"><input type="checkbox" ng-model="check" >data from database
</div>
<div class="col-md-8 col-xs-8 service-data">
<div class="row">
<div class="col-md-2 col-xs-2"></div>
<div class="col-md-2 col-xs-2">
<input type="number" class="form-data" ng-disabled="!check">
</div>
<div class="col-md-2 col-xs-2">
<input type="number" name="times" class="form-data" ng-disabled="!check">
</div>
<div class="col-md-2 col-xs-2">
<input type="text" class="form-data" ng-disabled="!check" ng-readonly="true" >
</div>
<div class="col-md-2 col-xs-2">
<input type="text" class="form-data" ng-disabled="!check" ng-readonly="true" >
</div>
<div class="col-md-2 col-xs-2">
<input type="text" class="form-data" ng-disabled="!check" ng-readonly="true" >
</div>
</div>
</div>
</div>
</div>
</div>
</uib-accordion-group>
</uib-accordion>
I don't know the specifics about your implementation, but you could make use of the CSS :before pseudo-element like I have done in this simple fiddle.
If you have a way of selecting the accordion header by the open/closed state, then you can do something similar to this:
.accordion li.open:before {
content: '- ';
}
.accordion li.closed:before {
content: '+ ';
}
glyphicon glyphicon-plusIf you want to handle this in javascript, you could use the collapse event described here.
shown.bs.collapse will fire when a collapse element has been made visible to the user (will wait for CSS transitions to complete).
hidden.bs.collapse will fire when a collapse element has been hidden from the user (will wait for CSS transitions to complete).
$('#yourCollapseDiv').on('shown.bs.collapse', function () {
$(".glyphicon").removeClass("glyphicon glyphicon-minus").addClass("glyphicon glyphicon-plus");
});
$('#yourCollapseDiv').on('hidden.bs.collapse', function () {
$(".glyphicon").removeClass("glyphicon glyphicon-plus").addClass("glyphicon glyphicon-minus");
});
It uses glyphicons to display the + and -

Angular-UI Bootstrap Modal grid row columns incorrect width

I am trying to build a form in boostrap angular-ui modal, and am having an issue with using the default bootstrap grid in the modal-body
I build a row and then immediately build a col-md-6 followed by another col-md-6 and it is overflowing and colums are not next to each other like I would expect. I'm at a loss on this one.
Here is the HTML I have for the modal
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-body">
<span class="glyphicon glyphicon-remove HoverMe pull-left CloseModalDark" ng-click="cancel()"></span>
<form>
<div class="row">
<div class="col-md-6">
<input type="text" ng-model="Name" class="form-control" placeholder="Full Name"/>
</div>
<div class="col-md-6">
<input type="text" ng-model="Name" class="form-control" placeholder="Your Email" />
</div>
</div>
</form>
</div>
I know it's bad practice to link to your site, but I don't know any other way to demonstrate this behavior.
The "Sign Our Guestbook" link is how the modal that I am referencing is opened.
The extra space you are seeing which is causing the overflow onto the new line is caused by your <span class="glyphicon glyphicon-remove HoverMe pull-left CloseModalDark" ng-click="cancel()"></span> due to a conflict between the position styles. The size and padding of the icon is still being set in place even though it's moved.
Because your close icon:
<span class="glyphicon glyphicon-remove HoverMe pull-left CloseModalDark" ng-click="cancel()"></span>
Its styles include position: relative;, which occupies 26px width of the .row. So the right input box is squeezed to next line. Make it position:absolute and adjust the left and top value. It will work.

Angular JS ng-show/ hide based on drop-down list selected value

in the following code I have one drop-down list (serviceSmallId) for type of service.
It is populated using model info.
There is a second field check-box which should only be visible when drop-down has a selected value of 'Weekly'. I am trying to use ng-show/ hide of angular.
I tried to search for possible solutions but no luck.
Can anyone please guide me what I am doing wrong.
<section id="scrubber-view" class="mainbar" data-ng-controller="scrubber as vm">
<section class="matter">
<div class="container">
<div>
<button class="btn btn-info" ng-click="vm.goBack()"><i class="fa fa-arrow-left"></i>Back</button>
<button class="btn btn-info" ng-click="vm.cancel()" ng-disabled="!vm.canSave"><i class="fa fa-undo"></i>Cancel</button>
<button class="btn btn-info" ng-click="vm.save()" ng-disabled="!vm.canSave"><i class="fa fa-save"></i>Save</button>
<span ng-show="vm.hasChanges" style="color:orange" class="dissolve-animation ng-hide"><i class="fa fa-asterisk"></i></span>
</div>
<div class="row">
<div class="widget wblue">
<div data-cc-widget-header title="{{vm.title}}" subtitle="{{vm.scrubber.scrubberId}}"></div>
<form class="form-horizontal">
<div class="form-group">
<label for="serviceSmallId" class="col-sm-2">Service</label>
<div class="col-sm-4">
<select class="form-control" id="serviceSmallId" ng-model="vm.scrubber.serviceSmallId"
ng-options="item.dataLookupId as item.description for item in vm.serviceSmalls | orderBy:['sortOrder','description']">
</select>
</div>
</div>
<div class="form-group" ng-show="vm.scrubber.serviceSmallId.value=='Weekly'">
<input class="form-control" type="checkbox" id="fullyFlanged" value="Bar" />
</div>
</form>
</div>
</div>
</div>
</section>
</section>
There probably is a more elegant "angular way" solution,
but I updated you code to work here - http://jsbin.com/tupisoriho/1/edit?html,js,output
Explanation of changes
Provided ng-show a value vm.checker
added ng-change to the select element and gave it a function checkerGo which tested to see if dropdown == 'weekly', if yes change vm.checker
Update
there is a more "angular way" - using expressions!
As per #Omri Aharon fiddle/comment below.
You don't need to get the value property because a ng-model don't hold the element but the value itself;
<div class="form-group" ng-show="vm.scrubber.serviceSmallId.value=='Weekly'">
must be
<div class="form-group" ng-show="vm.scrubber.serviceSmallId == 'Weekly'">
EDIT: In your case vm.scrubber.serviceSmallId will contain the ID and not the description Weekly. I suggest you to use ng-change directive to call a function in your controller that will find the item based on ID and set in the controller to be visible for ng-show.
<select class="form-control" id="serviceSmallId" ng-model="vm.scrubber.serviceSmallId"
ng-options="item.dataLookupId as item.description for item in vm.serviceSmalls | orderBy:['sortOrder','description']"
ng-change="vm.selectObj()">
vm.selectObj() will find and set the current selected object in the scope to an controller variable (ex.: vm.selectedItem) and:
<div class="form-group" ng-show="vm.selectedItem.description=='Weekly'">

Resources