I'm using Polymer and Dart to produce a list of point coordinates. It renders a list of points in html. Nevertheless I want to convert the points from one coordinate system to another using a javascript function.
In HTML dart-polymer:
<template repeat="{{ p in grid_points }}">
<core-item>{{ p }}</core-item>
</template>
The javascript I found in a library:
grid_to_geodetic(x, y);
grid_points is a List of Points. How can I pass p.x and p.y through the js function and get the result rendered in place of p in the HTML template?
You could use expression filter for that:
<template repeat="{{ p in grid_points }}">
<core-item>{{ p | grid_to_geodetic }}</core-item>
</template>
...
<script>
Polymer('your-element', {
grid_to_geodetic: function(point){
return point.x + point.y;
}
});
</script>
Filter takes one value and returns one, if you need to convert x and y separately you have to use an constant parameter to indicate which part of the point you want to convert, something like
<template repeat="{{ p in grid_points }}">
<core-item>{{ p | grid_to_geodetic(1) }}</core-item>
<core-item>{{ p | grid_to_geodetic(2) }}</core-item>
</template>
...
<script>
Polymer('your-element', {
grid_to_geodetic: function(point, part){
if(part == 1) return point.x;
else return point.y;
}
});
</script>
I did manage to invoke it thanks to some ideas from ain:
So with the expression filter you are telling the template to invoke a Dart function:
<template repeat="{{ p in start_points }}">
<core-item>{{ p | rt90_to_wgs84 }}</core-item>
</template>
Then in the Dart backing class you add a function with the same name as in the filter and you call a global js function with context.callMethod('funcion_name', [args_list]);:
rt90_to_wgs84(p) {
return context.callMethod('grid_to_geodetic', [p.x, p.y]);
}
Related
In my soup object, I have a div tag with two nested span tags and need to grab the "750 mL" from the first span and the "117" from the second span.
two span tags inside a div
I'm able to get into the first span tag using :
soup.find('div', class_='other_details').find('span')
Unfortunately, I can't get into the second span tag as it shares a div and class with the first. Can anyone suggest a way to grab the second span tag?
Another version using CSS selectors:
from bs4 import BeautifulSoup
txt = '''<div class="other_details">
<span tabindex="0">
750 ml
<span class="package-type"> bottle </span>
</span>
<span tabindex="0">
lCBO#:
<span>117</span>
</span>
</div>'''
soup = BeautifulSoup(txt, 'html.parser')
volume = soup.select_one('.other_details span:nth-child(1)').contents[0].strip()
number = soup.select_one('.other_details span:nth-child(2) span').text.strip()
print(volume)
print(number)
Prints:
750 ml
117
Can you show the link that you want to scrape?
The only thing I can help is to use the findAll() function for tabindex in BeautifulSoup
bottle = soup.findAll("tabindex")
print(bottle[0].text) #Output:750ml
print(bottle[1].text) #Output:LCBO#:
For getting 750 ml and 117, you can try it:
from bs4 import BeautifulSoup
html_doc = '''<div class="other_details">
<span tabindex="0">
750 ml
<span class="package-type"> bottle </span>
</span>
<span tabindex="0">
lCBO#:
<span>117</span>
</span>
</div>'''
soup = BeautifulSoup(html_doc, 'lxml')
spans = soup.find_all("span")
# print(spans)
for span in spans:
print(span.next_element.strip())
break
i = 0
for span in spans:
if i==1:
if span.span != None:
print(span.span.text)
i = 1
Output will be:
750 ml
117
My problem: building a Dart form according to the book. Below, my basic sample that looks like JS. It works fine but I get this warning: The getter value is not defined for the class Element.
My question: how can I write a better Dart code to avoid this warning message? Thanks.
HTML:
<form>
<input type="number" min="0" id="enter-x">
<input type="number" min="0" id="enter-y">
<input type="button" id="result" value="Submit">
<input type="reset" id="raz" value="Reset">
<input type="text" id="s" readonly>
</form>
DART:
import 'dart:html';
import 'dart:core';
main() {
document.querySelector('#result').onClick.listen((e) {
calculateS();
});
}
calculateS() {
var x = int.parse(document.querySelector('#enter-x').value);
var y = int.parse(document.querySelector('#enter-y').value);
var surface = (x * y).toString();
document.querySelector('#s').value = surface;
}
Dart helps with hints and warning to find errors in your program.
The generic Element doesn't have a value field. The Dart program is still valid and should work as expected and doesn't cause any errors or warnings at runtime because the actually returned element is the more specialized TextInputElement or NumberInputElement which has a value field.
To silence the analyzer, make this more clear by adding a "cast"
calculateS() {
var x = int.parse((document.querySelector('#enter-x') as NumberInputElement).value);
var y = int.parse((document.querySelector('#enter-y') as NumberInputElement).value);
var surface = (x * y).toString();
(document.querySelector('#s') as TextInputElement).value = surface;
}
Try it at DartPad
See also:
https://api.dartlang.org/1.12.0/dart-html/InputElement-class.html
Dart 'query' explicit cast
What is the syntax for implicit cast operator in dart?
https://www.dartlang.org/docs/dart-up-and-running/ch02.html#operators
I am trying to pull out lines in a tab delimited text file which contain all user-specified words exactly once (the sequence doesn't matter).
For example, I need to find lines which contain 'CA_', 'CS_', 'XV_' and 'JS_' exactly once.
Can I use grep for that?
Here is a possible solution. Is that what you are trying to do?
var rawString = 'CA_1234567 CA_R345335 CS_I8788765 CA_3456783 CS_0986887 CS_scaffolding2 CA_scaffolding3';
var valArr = rawString.split(' ');
//note: in real code, put CA, CA etc in an array and iterate
var CAItems = $.grep(valArr, function(val)
{
if (val.startsWith('CA'))
{
return val;
}
});
var CSItems = $.grep(valArr, function(val)
{
if (val.startsWith('CS'))
{
return val;
}
});
$('#CAValuesTxt').text(CAItems.join(' '))
$('#CSValuesTxt').text(CSItems.join(' '))
String.prototype.startsWith = function (prefix) {
return this.indexOf(prefix) === 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<label>Values starting with CA: </label>
<label id='CAValuesTxt'></label>
<br/>
<br/>
<label>Values starting with CS: </label>
<label id='CSValuesTxt'></label>
I hope it helps!
Here's the scenario:
I am using an ASP.NET MVC site with Angular JS and Boostrap UI. I have a dynamic ul list populated by data fed through a controller call to AngularJS, filtering on that list through an input search box. The list is also controlled through pagination (UI Bootstrap control) that I've setup to show 10 results per page for the list of 100 or so items. This list is filtered as the user types in the search box, however I would like the pagination to update as well so consider the following example:
The list has 10 pages of items (100 items), the user types some text in the input search box which filters the list down to 20 or so items, so the pagination should be updated from 10 pages to two pages.
I figure there must be a $watch setup somewhere, perhaps on the list items after it has been filtered and then update the pagination page count, however I'm pretty new to AngularJS so can someone please explain to me how this could be done?
Thanks very much. I have posted my code below:
<div data-ng-app="dealsPage">
<input type="text" data-ng-model="cityName" />
<div data-ng-controller="DestinationController">
<ul>
<li data-ng-repeat="deals in destinations | filter: cityName |
startFrom:currentPage*pageSize | limitTo:pageSize">{{deals.Location}}</li>
</ul>
<br />
<pagination rotate="true" num-pages="noOfPages" current-page="currentPage"
max-size="maxSize" class="pagination-small" boundary-links="true"></pagination>
</div>
var destApp = angular.module('dealsPage', ['ui.bootstrap', 'uiSlider']);
destApp.controller('DestinationController', function ($scope, $http) {
$scope.destinations = {};
$scope.currentPage = 1;
$scope.pageSize = 10;
$http.get('/Deals/GetDeals').success(function (data) {
$scope.destinations = data;
$scope.noOfPages = data.length / 10;
$scope.maxSize = 5;
});
});
destApp.filter('startFrom', function () {
return function (input, start) {
start = +start; //parse to int
return input.slice(start);
};
});
Because your pagination is a combination of chained filters, Angular has no idea that when cityName changes, it should reset currentPage to 1. You'll need to handle that yourself with your own $watch.
You'll also want to adjust your startFrom filter to say (currentPage - 1) * pageSize, otherwise, you always start at page 2.
Once you get that going, you'll notice that your pagination is not accurate, because it's still based on destination.length, and not the filtered sub-set of destinations. For that, you're going to need to move your filtering logic from your view to your controller like so:
http://jsfiddle.net/jNYfd/
HTML
<div data-ng-app="dealsPage">
<input type="text" data-ng-model="cityName" />
<div data-ng-controller="DestinationController">
<ul>
<li data-ng-repeat="deals in filteredDestinations | startFrom:(currentPage - 1)*pageSize | limitTo:pageSize">{{deals.Location}}</li>
</ul>
<br />
<pagination rotate="true" num-pages="noOfPages" current-page="currentPage" max-size="maxSize" class="pagination-small" boundary-links="true"></pagination>
</div>
JavaScript
var destApp = angular.module('dealsPage', ['ui.bootstrap']);
destApp.controller('DestinationController', function ($scope, $http, $filter) {
$scope.destinations = [];
$scope.filteredDestinations = [];
for (var i = 0; i < 1000; i += 1) {
$scope.destinations.push({
Location: 'city ' + (i + 1)
});
}
$scope.pageSize = 10;
$scope.maxSize = 5;
$scope.$watch('cityName', function (newCityName) {
$scope.currentPage = 1;
$scope.filteredDestinations = $filter('filter')($scope.destinations, $scope.cityName);
$scope.noOfPages = $scope.filteredDestinations.length / 10;
});
});
destApp.filter('startFrom', function () {
return function (input, start) {
start = +start; //parse to int
return input.slice(start);
};
});
The version shared on jsfiddle is compatible with ui-bootstrap 0.5.0 but from 0.6.0 onwards there have been breaking changes.
Here is a version that uses the following libraries:
angular 1.2.11
angular-ui-bootstrap 0.10.0
bootstrap 3.1.0
Here is a plunker for the same:
Angular UI Bootstrap Pagination
Hello I tried to hook this up with Firebase using Angular Fire and it only works after I type something in the search input. In the $scope.$watch method, I used Angular Fire's orderByPriorityFilter to convert the object to an array.
$scope.$watch('search', function(oldTerm, newTerm) {
$scope.page = 1;
// Use orderByPriorityFilter to convert Firebase Object into Array
$scope.filtered = filterFilter(orderByPriorityFilter($scope.contacts), $scope.search);
$scope.lastSearch.search = oldTerm;
$scope.contactsCount = $scope.filtered.length;
});
Initial load doesn't load any contacts. It's only after I start typing in the input search field.
I have multiple pages generated using PDFKit. How can I add page numbers to the bottom?
PDFKit.configure do |config|
config.default_options = {
header_right: "Page [page] of [toPage]"
}
end
kit = PDFKit.new(body_html)
Read all detailed documentation here:
http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html
PDFKit is just a wrap up for wkhtmltopdf application that is written in C.
you need to specify a footer like this:
kit = PDFKit.new(your_html_content_for_pdf, :footer_html => "#{path_to_a_footer_html_file}")
then in the footer file have this:
<html>
<head>
<script type="text/javascript">
function subst() {
var vars={};
var x=document.location.search.substring(1).split('&');
for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
for(var i in x) {
var y = document.getElementsByClassName(x[i]);
for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
}
}
</script>
</head>
<body style="margin: 0;" onload="subst();">
Page <span class="page"></span> of <span class="topage"></span>
</body>
</html>
elements of classes 'frompage','topage','page','webpage','section','subsection','subsubsection' will get substituted with the appropriate data
I did page number with PDFKit, just by adding this:
%meta{:name => 'pdfkit-footer_right', :content => "[page]"}
in my haml file, in my RoR project.
For some weird reason, ( perhaps because I'm using slim ) - I have to use single quotes around the content, instead of double quotes - or else it attempts to escape the brackets and raw text "[page]" shows up, so try single quotes if you run into this issue with your pages.