Displaying dynamic content in bootstrap popover with angular - javascript

I have a page that displays some fields from an object provided by a service using angular 2. I would like to display some of those fields only when the user hovers over some div. I thought the bootstrap popover would be ideal but I am not sure how to display those extra fields in the data-content element of the bootstrap popover. Here it is my attempt code.
div class="container">
<div class="row">
<div class="col-sm-4 col-lg-4 col-md-4" data-toggle="tooltip" title="Name">
{{data.name}}
</div>
<div class="col-sm-2 col-lg-2 col-md-2" data-toggle="tooltip" title="A Date">
{{data.aDate | date:'shortDate'}}
</div>
<div class="col-sm-2 col-lg-2 col-md-2" data-toggle="tooltip" title="other">
{{data.other}}
</div>
<div class="col-sm-4 col-lg-4 col-md-4" data-toggle="popover" title="More data" data-content="how to display data.field1, data.field2" >
Popover test
</div>
</div>
</div>
In the popover data-content I would like to display a multiple row that would look like
field1: {{data.field1}}
field2: {{data.field2}}
I am new to both bootstrap and angular, perhaps a popover is not even the best way to display this data?

Related

Selenium - cannot click on an element inside a modal

I am using Selenium and java and I cannot click on an element inside a modal.
The scenario is this:
after clicking on an item inside a frame, it opens up a modal and I need to click on an element inside this modal but I cannot get it.
I already tried with:
js.executeScript("document.getElementById('saveexit').scrollIntoView(true);");
I also tried with switchTo() this way:
while (itr.hasNext()) {
String popup = itr.next();
System.out.println("itr: " + popup);
driver.switchTo().window(popup);
}
Here is the html of my modal:
<div class="modal-dialog">
<div class="modal-content modal-custom-content">
<div class="modal-header">
...
</div>
<div class="modal-body">
<form id="formTo" class="form-container">
<div class="row">
...
</div>
<div class="small-space"></div>
<input ...>
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12">
...
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12">
...
</div>
</div>
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12">
...
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12">
...
</div>
</div>
<div class="small-space"></div>
<div class="row">
...
</div>
</form>
</div>
<div class="small-space"></div>
<div class="modal-footer">
<div class="row text-center">
<div class="col-md-6 col-sm-6 col-xs-12">
<button class="btn modal-button full-btn" id="saveexit" type="button">SAVE AND EXIT</button>
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
...
</div>
</div>
</div>
</div>
</div>
this is the CSS Path as taken from firefox dev tool:
html.no-touch body div.remodal-wrapper.remodal-is-opened div.modaliAdesione.remodal.remodal-is-initialized.remodal-is‌​-opened div.modal-dialog div.modal-content.modal-custom-content div.modal-footer div.row.text-center div.col-md-6.col-sm-6.col-xs-12 button#saveexit.btn.modal-button.full-btn
the object is never found.
Question 1: if an element is inside a modal has to be managed
differently?
Question 2: How to finally have the click on the button
saveexit working?
here is shared a code snippet of the html: https://codeshare.io/arLW9q
Here is the java code:
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id=\"saveexit\"]")))
I have also tried with:
cssSelector: #saveexit
cssPath: html.no-touch body div.remodal-wrapper.remodal-is-opened div.modaliAdesione.remodal.remodal-is-initialized.remodal-is-opened
div.modal-dialog div.modal-content.modal-custom-content div.modal-footer div.row.text-center div.col-md-6.col-sm-6.col-xs-12
button#saveexit.btn.modal-button.full-btn
xpath: //*[#id="saveexit"]
Please note: if I run document.getElementById('saveexit').click(); from browser's console it works out
As you are using the Selenium-Java clients as per best practices the first and foremost trial must be with invoking the highly efficient and proven click() method. Depending on the errors resulting out of click() method we can work on other alternate solutions.
As I can see from your code trials with JavascriptExecutor and switchTo().window(), you havn't identified the WebElement representing the SAVE AND EXIT button well.
To click on the SAVE AND EXIT button you can use the following code block :
new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#class='modal-dialog']//div[#class='modal-footer']//button[#class='btn modal-button full-btn' and #id='saveexit']"))).click();
I fixed it using jquery inside my script;
here is the linecode:
js.executeScript("$('#saveexit').trigger('click');");
I hope it can help someone in future.
I dont know why plain javascript was not working...

Bootstrap Grid Re-sizing content to new location on page

I'm new to boot strap so I may be thinking of this objective in an incorrect way, so I would appreciate any advice as well as a solution.
Say for example I have a left column
<div class="row">
<div class="col-md-3 col-xs-6">Some Data 0</div>
<div class="col-md-3 col-xs-6">Some Data 1</div>
<div class="col-md-3 col-xs-6">Some Data 2</div>
</div>
When the screen matches the XS I would like "Some Data 0" to be wrapped in a modal component. So that "Some Data 0" is now hidden in a modal window and a button is in it's place that when clicked will display the modal window with the content "Some Data 0"
How is this accomplished in Bootstrap. Is the only way to duplicate "Some Data 0" and just show and hide based on the screen breakpoints?
Thanks
Well you can achieve it in this way i guess :
<div class="row">
<div class="col-md-3 hidden-xs">Some Data 0</div>
<div class="col-xs-12 hidden-md visible-xs"> Handle your modal with Some Data 0 in this div</div>
<div class="col-md-3 hidden-xs">Some Data 1</div>
<div class="col-xs-12 hidden-md visible-xs">Handle your modal with Some Data 1 in this div</div>
<div class="col-md-3 hidden-xs">Some Data 2</div>
<div class="col-xs-12 hidden-md visible-xs">Handle your modal with Some Data 2 in this div</div>
</div>
Key feature here is to use hidden-{} and visible-{} classes.

Slow performance rendering in client templating engine (Rivets.js)

I'm rendering an array of of about 1000 objects. The html bindings are very heavy (see below). It's taking about 5 seconds to rivets.bind().
Any suggestions on improving performance? I don't think I can afford to bind in chunks as I'm using a pagination/sorting library in conjuction that needs the entire array in order to sort/paginate.
Here is my HTML for each object (tracks):
<div rv-each-track="tracks" class="track-row row has-hover" rv-download-url="track.direct_path.download_path" rv-api-key="track.track.apikey" rv-media-url="track.direct_path.audio" rv-track-title="track.track.name" rv-wave-data="track.direct_path.wave_default" rv-wave-progress-data="track.direct_path.wave_progress">
<div class="mobile-margin">
<div class="track-hover desktop-only">
<div class="hover-play icon-play inline-play"></div>
<div class="hover-title">{track.track.name}<span rv-class="track.track.staff_pick | staffPickClass" data-toggle="tooltip" data-original-title="Staff Pick"></span></div>
<div class="hover-links">
<div class="item hamburger holds-tooltip main-hover-item icon-hamburger" data-toggle="tooltip" data-original-title="Alternate Versions"></div>
<div class="item share main-hover-item popover-button icon-share" data-target="#not-ready-popover"><div class="tooltip-holder holds-tooltip" data-toggle="tooltip" data-original-title="Share Track"></div></div>
<div class="item playlist icon-playlist-add popover-button holds-tooltip main-hover-item" data-target="#playlist-popover" data-toggle="tooltip" data-original-title="Add to Playlist"></div>
<div class="item download icon-download holds-tooltip main-hover-item" data-toggle="tooltip" data-original-title="Download Track"></div>
<div class="item cart last icon-cart-plus holds-tooltip main-hover-item popover-button" data-target="#not-ready-popover" data-toggle="tooltip" data-original-title="Add to Cart"></div>
<div class="item remove last icon-x holds-tooltip main-hover-item" data-toggle="tooltip" data-original-title="Remove Track" rv-data-delete-track-id="track.track.apikey"></div>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
<div class="track-variations">
<div rv-each-variation="track.variations.tracks" class="row variation-row" rv-data-track-id="track.track.apikey" rv-api-key="variation.track.apikey" rv-media-url="variation.direct_path.audio" rv-track-title="variation.track.name" rv-wave-data="variation.direct_path.wave_default" rv-wave-progress-data="variation.direct_path.wave_progress">
<div class="col-md-8 variation-title">{variation.track.name}</div>
<div class="col-md-2 variation-length">{variation.track.tracklength}</div>
<div class="track-hover variation">
<div class="hover-play icon-play inline-play"></div>
<div class="hover-title"><a class="track-link">{variation.track.name}</a></div>
<div class="hover-links">
<div class="item share popover-button icon-share" data-target="#not-ready-popover"><div class="tooltip-holder holds-tooltip" data-toggle="tooltip" data-original-title="Share Track"></div></div>
<div class="item playlist popover-button icon-playlist-add" data-target="#playlist-popover" data-toggle="tooltip" data-original-title="Add to Playlist" data-placement="left"></div>
<div class="item download icon-download" rv-data-media-url="track.direct_path.download_path" data-toggle="tooltip" data-original-title="Download Track" data-placement="left"></div>
<div class="item cart last icon-cart-plus holds-tooltip popover-button" data-target="#not-ready-popover" data-toggle="tooltip" data-original-title="Add to Cart"></div>
<div class="item last remove main-hover-item icon-x"></div>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
</div>
</div>
<div class="no-variations" rv-hide="track.variations.tracks | shouldHideNoVariations">There are no alternate versions of this track.</div>
</div>
</div>
<div class="col-md-4 first-title desktop-only"><a class="offset-left track-title-link track-link" href="">{track.track.name}</a><span rv-class="track.track.staff_pick | staffPickClass" data-toggle="tooltip" data-original-title="Staff Pick"></span></span></div>
<div class="col-md-3 genre desktop-only"><span class="offset-left">{track.genre}</span></div>
<div class="col-md-2 mood desktop-only"><span class="offset-left">{track.mood}</span></div>
<div class="col-md-2 canvas desktop-only"><div class="mini-wave offset-left" rv-style-background-image="track.direct_path.wave_canvas"></div></div>
<div class="col-md-1 last-title duration desktop-only"><span>{track.track.tracklength}</span></div>
<div class="col-md-1 last-title last-played pull-right desktop-only">{track.lastPlayed}</div>
<div class="mobile-play icon-play pull-left mobile-only inline-play"></div>
<div class="mobile-track-title mobile-only track-row-item-margin"><div class="track-title-link">{track.track.name}</div><span rv-class="track.track.staff_pick | staffPickClass"></span></div>
<div class="mobile-track-buttons pull-right">
<div class="pull-right mobile-only mobile-button mobile-track-menu-button left-margin icon-plus"></div>
<div class="pull-right mobile-only mobile-button mobile-variations-button icon-hamburger"></div>
</div>
<div class="is-staff-pick hidden">{track.track.staff_pick | staffPickValue}</div>
<div class="instrument hidden">{track.instrument}</div>
<div class="industry hidden">{track.industry}</div>
<div class="tempo hidden">{track.tempo}</div>
<div class="aggregated-terms hidden">{track.tag_list} {track.track.name}</div>
<div class="date-last-played hidden">{track.dateLastPlayed}</div>
<div class="clearfix"></div>
</div>
<div class="track-variations mobile-only">
<div rv-each-variation="track.variations.tracks" class="row variation-row" rv-api-key="track.track.apikey" rv-media-url="variation.direct_path.audio" rv-track-title="variation.track.name">
<div class="mobile-margin">
<div class="col-md-8 variation-title desktop-only">{variation.track.name}</div>
<div class="col-md-2 variation-length desktop-only">{variation.track.tracklength}</div>
<div class="track-hover variation">
<div class="hover-play icon-play inline-play"></div>
<div class="hover-title">{variation.track.name}</div>
<div class="hover-links">
<div class="item share popover-button icon-share" data-target="#not-ready-popover"><div class="tooltip-holder holds-tooltip" data-toggle="tooltip" data-original-title="Share Track"></div></div>
<div class="item playlist popover-button icon-playlist-add" data-target="#playlist-popover" data-toggle="tooltip" data-original-title="Add to Playlist" data-placement="left"></div>
<div class="item download icon-download" data-toggle="tooltip" data-original-title="Download Track" data-placement="left"></div>
<div class="item cart last icon-cart-plus holds-tooltip popover-button" data-target="#not-ready-popover" data-toggle="tooltip" data-original-title="Add to Cart"></div>
<div class="item last remove main-hover-item icon-x"></div>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
</div>
<div class="mobile-play icon-play pull-left mobile-only inline-play"></div>
<div class="mobile-track-title mobile-only track-row-item-margin"><div class="track-title-link">{variation.track.name}</div></div>
<div class="mobile-track-buttons pull-right">
<div class="pull-right mobile-only mobile-button mobile-track-menu-button left-margin icon-plus"></div>
</div>
</div>
</div>
<div class="no-variations" rv-hide="track.variations.tracks | shouldHideNoVariations">There are no alternate versions of this track.</div>
</div>
Do not do rivets events example: rv-click which will degrade your performance because you will be passing your entire view for the callback method.
DO not pass entire view to the rivets.bind()
pass only the necessary models and do it.
If it is possible first bind 100 elements and then if user scrolled half of the page bind again 100 elements which will improve your performance for sure.
I did the below changes in binders to make it run faster even in lower end mobile devices as well.
rivets.binders.text = function(el, value) {
if (el.textContent != null) {
return el.textContent;
}
else {
return el.innerText;
}
};
I've come to the the conclusion that yes, there are minor performance improvements that I could potentially implement for binding 1000+ (large html) objects to the DOM using Rivets. However, the root issue is the fact that I'm trying to bind 1000+ rivets into the DOM at once and that is going to be inherently slow using any technique (I've tested with React, jQuery, Rivets, etc...).
The solution to this problem is to simply find another way. I've chosen to pre-render the html on the server and serve it up through an API response. This cut the page load time down from ~5s to ~1s.

Angularjs - auto submit the first item

I want to select the first item in my ng-repeat as soon the list is loaded to the user, is there an easy way to do that?
Right now im using the ng-click, but i dont know how to automatic click that first item.
This is my ng-repeat
<div ng-hide="hideMembershipSection" ng-repeat="membership in memberships" class="row">
<div class="membership-box col-lg-9 col-md-9 col-sm-9 col-xs-8">
<img class="img-responsive" ng-src="/images/onlinesalg_ny/{{ membership.image }}">
<h1 class="text-uppercase">{{ membership.titel_onlinesalg }}</h1>
<p>{{ membership.onlinesalg_produktbeskrivelse }}</p>
</div><!-- col-lg-9 -->
<div class="membership-box__price col-lg-3 col-md-3 col-sm-3 col-xs-4 text-center">
<h1>
<small>Kr.</small>
{{ membership.pris }},-
</h1>
<button ng-click="selectMembership(membership)" type="button" ng-class='{"btn-success": membership.pid == success}' class="text-uppercase btn btn-primary" ng-disabled="membership.pid == success">{{ membership.pid === success ? "valgt" : "vælg"}}</button>
</div><!-- col-lg-9 -->
In the controller, after the code where you load the list into $scope.memberships, what about using the line:
selectMembership($scope.memberships[0]);
This is essentially doing what ng-click is doing, but after the list is loaded. It depends on what your selectMembership function does though.
you can use ng-init to select first element by default as in ng-init="ngModelFieldName=memberships[0]
i dont know the name of the ng-model hence gave the name ngModelFieldName
<div ng-hide="hideMembershipSection" ng-repeat="membership in memberships" ng-init="ngModelFieldName=memberships[0]" class="row">

AngularJS ng-repeat, $scope variable issue and preventing infinite $digest loop

I need to find a better solution regarding ng-repeat, $scope variable and infinite $digest loop. I'm sure it's not $watch issue and I'm sure it's in the way I'm updating my $scope variable.
The issue doesn't happen in Chrome. It only happens in Safari and Firefox. This is how I'm doing it. I have a $scope.chartCollection which is dynamically populated with Google Chart objects. The $scope.chartCollection can have 1 or more google chart objects depending on my selection.
In my html template, I have this code,
<div ng-repeat="device in chartCollection">
<div class="col-md-6 padding10px">
<div class="widget enable-top-radius chartProperties">
<div class="widget-title enable-top-radius dark-gray-title">
<h4>
<span class="alignleft">
<i class="fa fa-circle" ng-style="{ color : device.dotColor }"></i><span class="padding5px">{{printerTypeName}}</span><span class="padding5px">|</span><span class="padding5px" popover="{{device.modelOrLocation }}" popover-trigger="mouseenter">{{ device.modelOrLocation }}</span>
</span>
</h4>
<span class="alignright">{{device.location | uppercase }}</span>
<div style="clear: both;" class="padding5px"></div>
</div>
<div class="widget-body">
<div google-chart chart="device.chart" on-select="seriesSelected(selectedItem, $index)"></div>
</div>
</div>
<div class="col-md-12 col-sm-12 col-xs-12 no-padding chartInfoBox">{{dateForGraph}}</div>
<div class="col-md-12 col-sm-12 col-xs-12 no-padding">
<div class="col-md-4 col-sm-4 col-xs-4 odometerChartFooter">
<div class="odometerFooterFieldValue" ng-bind="device.leftCellNumber | number"></div>
<div class="odometerFooterFieldKey" ng-bind="device.leftCellText"></div>
</div>
<div class="col-md-4 col-sm-4 col-xs-4 odometerChartFooter">
<div class="odometerFooterFieldValue" ng-bind="device.middleCellNumber | number"></div>
<div class="odometerFooterFieldKey" ng-bind="device.middleCellText"></div>
</div>
<div class="col-md-4 col-sm-4 col-xs-4 odometerChartFooter">
<div class="odometerFooterFieldValue" ng-bind="device.rightCellNumber | number"></div>
<div class="odometerFooterFieldKey" ng-bind="device.rightCellText"></div>
</div>
</div>
</div>
</div>
so that I can display each chart in separate divs. It works really well in Chrome but not in Firefox and Safari.
I'm getting this error in Firefox and Safari
https://docs.angularjs.org/error/$rootScope/infdig?p0=10&p1=%5B%5B%5D,%5B%5D,%5B%5D,%5B%5D,%5B%5D%5D
And my situation is similar to the second example they mentioned which generates a new array. However, in my situation, it will always be a new array.
I was thinking of not using ng-repeat and use $scope.chart1, $scope.chart2 etc but the problem with this approach is that I cannot tell if there will be 1, 10 or 20 charts since everything is generated dynamically. Code will be very messy!
Update:
Here is the code that generates the chart objects
http://pastebin.com/DmQkDHjW

Categories