Bind table with dynamic rows and columns from two lists - dart

I'm trying to create a family-calendar style app that has a table with names of persons as columns and dates as rows. Not sure how to do this but this is what I have so far:
calendartable.html
<polymer-element name="calendar-table">
<template>
<table>
<tr template repeat="{{dates}}">
<td template repeat="{{people}}">{{name}}</td>
</tr>
</table>
</template>
<script type="application/dart" src="calendartable.dart"></script>
</polymer-element>
calendartable.dart
import 'package:polymer/polymer.dart';
class Person
{
String name;
Person(this.name);
}
#CustomTag('calendar-table')
class CalendarTable extends PolymerElement {
List people = [new Person("Kalle"), new Person("Olle")];
List dates = [new DateTime(2013, 09, 09), new DateTime(2013, 09, 10)];
}
Some questions about the above:
The above code does not work, "Uncaught Error: EvalException: variable not found: people in 193757919". Is this due to this bug or am I doing something else wrong?
Is there another way to create tables with both dynamic rows and columns? Maybe some workaround if the bug is affecting my code?
Is there any docs about using "template" as an attribute rather than an element? (Just saw some other code that used it as an attribute and it seems to work but cannot find any official docs)
UPDATE:
The output I am looking for is something like this. (I plan to add content for the "X" in the cells once I have the basic layout rendering correctly):
+------------+-------+------+
| | Kalle | Olle |
+------------+-------|------+
| 2013-09-09 | X | X |
+------------+-------+------+
| 2013-09-10 | X | X |
+------------+-------+------+
UPDATE:
This is what I ended up with that works (thanks to ianmjones for pointing me in the right direction!):
calendartable.html
<polymer-element name="calendar-table">
<template>
<table>
<tr>
<td></td>
<template repeat="{{person in people}}">
<td>{{person.name}}</td>
</template>
</tr>
<template repeat="{{date in dates}}">
<tr>
<td>{{date.toString()}}</td>
<template repeat="{{person in people}}">
<td>X</td>
</template>
</tr>
</template>
</table>
</template>
<script type="application/dart" src="calendartable.dart"></script>
</polymer-element>

I think this is what you want, or at least will get you closer.
<polymer-element name="calendar-table">
<template>
<table>
<template repeat="{{date in dates}}">
<tr>
<td>{{date.toString()}}</td>
<template repeat="{{person in people}}">
<td>{{person.name}}</td>
</template>
</tr>
</template>
</table>
</template>
<script type="application/dart" src="calendartable.dart"></script>
</polymer-element>
This should give you as many rows as there are dates, first column is date (needs some formatting), next columns contain name of each person.
e.g:
2013-09-09 00:00:00.000 Kalle Olle
2013-09-10 00:00:00.000 Kalle Olle

This answer no longer applies after the question was updated.
I am not sure how your table cells are laid out. In your implementation, for example, there is no place to output the date value.
Assuming I haven't completely misunderstood the layout you want, you could rewrite your element <template> content as follows:
<polymer-element name="calendar-table">
<template>
<table>
<tr>
<td template repeat="{{people}}">{{name}}</td>
</tr>
<tr>
<td template repeat="{{dates}}">{{}}</td>
</tr>
</table>
</template>
<script type="application/dart" src="calendartable.dart"></script>
</polymer-element>
That would put the 2 names in the first row, and the two dates in the second row (if that is in fact what you want).

Related

Capybara: Pulling in multiple Radio button options

Im running into an issue, and I think the issue is with how my page.all is pulling radio button questions in.
So here is the HTML for the table itself (Multiple questions with 5 radio button choices a piece):
<table class="table table-striped table-stuff table-collapsible">
<colgroup>
<thead>
<tbody>
<input id="0_answer_question_id" value="9966" name="response[answers][0][answer_id]" type="hidden">
<tr>
<td class="heading">
<td class="option">
<div class="radio-inline radio-inline--empty">
<input id="question_1_1" value="1" name="response[answers_attributes][0][answer_opinion]" type="radio">
<label for="question_1_1">Strongly Disagree</label>
</div>
</td>
<td class="option">
<td class="option">
<td class="option">
<td class="option">
</tr>
<input id="response_1_question_id" value="9966" name="response[answers_attributes][1][answer_question_id]" type="hidden">
<tr>
<input id="response_1_id" value="<a number>" name="response[answers_attributes][1][id]" type="hidden">
<Same as above repeated 5 times with numbers changed>
</tbody>
</table>
Im using:
page.all('table.table-stuff tbody tr', minimum: 6).each do |row|
row.all("td label").sample.trigger('click')
end
To get each row and select one from it. HOWEVER, I notice "sometimes" a row will not have one selected. My theory is the "heading" (which has a <label> itself is accepting one of the clicks perhaps? (since from my understanding of how page.all works it's grabbing every tbody tr within the table...but is maybe grabbing the heading too? (since it contains a td label?)
Also when a table is named something like table table-striped table-stuff table-collapsible...how can you tell what the actual table "name" is? (I didn't write this website, just doing tests for it). When putting it in the page.all('table.<etc>')?
If the heading td (it's not expanded in your example) also contains a label element (so it would be included in the results of your all call) then you just need to change the CSS selector so it wouldn't be included - something like
row.all("td.option label").sample.trigger('click') # only choose labels contined in tds with the class of 'option'
or
row.all("td:not(.heading) label").sample.trigger('click') # choose labels contained in tds without the class of 'heading'
On your second question about table names, I don't really understand what you're asking. Tables don't have name attributes, they could have an id attribute or a caption containing some text which could then be used to find them with capybara via find(:table, 'id or caption text') or within_table('id or caption text') { code to execute within scope of the table }. Rather, you seem to be talking about the classes on the element which are specified in a CSS selector with '.'. Therefore a CSS selector to match a table element with all the classes you listed would be - 'table.table.table-striped.table-stuff.table-collapsible'
Note: If you're sure there's always only 5 choices you could add the :count option to your find to make sure your selector is only finding those items
row.all("td.option label", count: 5).sample.trigger('click')

Change <template> (TemplateElement) programmatically

Going back to my question Query elements inside <content> of a custom element
Now I would like to programmatically change the template of the nested custom element before start of rendering. Is it possible?
<polymer-element name="my-element">
<template>
<div>
<template id="tml" repeat="{{items}}">
Hi, {{}}!
</template>
</div>
</template>
<script type="application/dart" src="my_element.dart"></script>
</polymer-element>
<polymer-element name="my-decorator">
<template>
<div>
<div>Decorator</div>
<content>
<!-- my-element will be here-->
</content>
</div>
</template>
<script type="application/dart" src="my_decorator.dart"></script>
</polymer-element>
in index.html:
<my-decorator>
<my-element></my-element>
</my-decorator>
in my_decorator.dart:
#override
void enteredView() {
super.enteredView();
ContentElement content = shadowRoot.querySelector('content');
MyElement elm = content.getDistributedNodes().firstWhere((e) => e is MyElement);
TemplateElement elm = elm.shadowRoot.querySelector("#tml");
// TODO
// change template here!
}
Why would you change the template?
In attached() after super.attached() the element is already rendered.
You can access the template with this.templateInstance
and try to change it before super.attached() (or in the constructor or in polymerCreated).
I haven't done this myself yet.
It's no problem to change the rendered element.
If you want to avoid that the this change is visible, you can set a (CSS) class initially which is defined to render the element invisible and after you are done with your changes, remove this class.

How to create a <select> element with polymer-dart repeat

I am trying to iterate a list to create a select drop-down box. My code is shown below as a web component
<!DOCTYPE html>
<polymer-element name="epimss-name">
<template>
<label for='titleCmbo' id='titleLbl'>Title</label>
<template repeat="{{title in titleList}}">
<select id='titleCmbo'>
<option value='{{title}}'>{{title}}</option>
</select>
</template>
</template>
<script type="application/dart">
import 'package:polymer/polymer.dart';
#CustomTag( 'epimss-name' )
class NameElement extends PolymerElement
{
final List<String> titleList = toObservable([ '', 'Dr', 'Miss', 'Mr', 'Mrs', 'Prof' ]);
}
</script> </polymer-element>
</body>
</html>
As the code is, it creates a separate combo for each iteration.
If I move the tags outside of the nested template, the editor complains.
What is the proper way to do this?
Thanks
You can use the template attribute on the option tag. It will repeat the option element and loop value for each item in the template collection.
<select id="titleCmbo">
<option value="{{title}}" template repeat="{{title in titleList}}">
{{title}}
</option>
</select>

Drag and drop reordering of table rows with ASP.NET MVC implementation issue

I have an ASP.NET MVC 4 web application. On a web page, I have a HTML table presenting a number of items.
I want to be able to implement drag and drop re-ordering for the table of items, which is saved back to the data model.
I've looked at and tried a few different methods for doing this, using JQuery UI and some other plugins but I haven't successfully been able to implement the functionality.
I've looked at this example, but my table didn't change on running it after implementing it as follows:
<script type="text/javascript">
$(document).ready(function()
{
$('#clueTable tbody').sortable().disableSelection();
});
</script>
I have all the necessary javascript:
<script type="text/javascript" src="~/Scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="~/Scripts/jquery-ui-1.10.2.min.js"></script>
I'm not going to post the whole table, but it looks something like this:
<table id="clueTable" class="grid">
<thead>
<tr>
<th>Clue #</th>
<th>Location</th>
<th>Quiz Clue?</th>
<th>Actions</th>
</tr>
</thead>
#for (int i = 0; i < Model.Clues.Count; i++)
{
<tbody>
<tr>
<td>Number</td>
<td>Things</td>
<td>Yes</td>
<td>Stuff</td>
</tr>
</tbody>
}
</table>
The duplicated tbody tags are your problem.
Works:
http://jsfiddle.net/vR9UW/
Doesn't work:
http://jsfiddle.net/vR9UW/1/

google chartapi custom html datasource query times out

I am simply trying to implement what I believe is google's example of a custom HTML data-source. I am clearly missing something but am unable to see it.
The goal is to have my default page retrieve a table's worth of data from my own data-source and chart it.
The error I receive is eventually I get a timeout dialog displayed.
I have two files default.htm and data.htm. For a period of time this will also be on the associated website. (www.ichoosewellness.com/chartapitest).
default.htm:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', { packages: ['corechart'] });
</script>
<script type="text/javascript">
function drawVisualization() {
// Replace the data source URL on next line with your data source URL.
var query = new google.visualization.Query('http://www.ichoosewellness.com/chartapitest/data.htm?tqx=reqId:1;out:html');
// Send the query with a callback function.
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
// Create and draw the visualization.
var comboChart = new google.visualization.ComboChart(document.getElementById('chart_div'));
comboChart.draw();
var div = document.getElementById('chart_div');
div.style.backgroundColor = 'red';
}
google.setOnLoadCallback(drawVisualization);
var div = document.getElementById('chart_div');
div.style.backgroundColor = 'red';
</script>
</head>
<body>
<div id='chart_div' style="width: 500px; height: 250px; border: 1px solid green;">
</div>
</body>
</html>
data.htm
<html>
<body>
<table border='1' cellpadding='2' cellspacing='0'>
<tr style='font-weight: bold; background-color: #aaa;'>
<td>
label 1
</td>
<td>
label 2
</td>
</tr>
<tr bgcolor='#f0f0f0'>
<td align='right'>
1
</td>
<td>
a
</td>
</tr>
<tr bgcolor='#ffffff'>
<td align='right'>
2
</td>
<td>
b
</td>
</tr>
<tr bgcolor='#f0f0f0'>
<td align='right'>
3
</td>
<td>
c
</td>
</tr>
<tr bgcolor='#ffffff'>
<td align='right'>
4
</td>
<td>
d
</td>
</tr>
</table>
</body>
</html>
This question is pretty old now but I will add what I found out about it since I had a similar problem.
Basically I was trying to get google.visualization.Query() to call my WCF REST service and have it return a json dataTable. Every time the query executed, it would throw a timeout error even though the GET request executed successfully. The culprit turned out to be the formatting of the response string and cross site domain permissions.
The response format is very particular and would throw a timeout error if not correctly defined. You have to go over the response format with a fine tooth comb and read the detailed documentation below.
Here is the URL that explain in detail the proper format:
http://code.google.com/apis/chart/interactive/docs/dev/implementing_data_source.html1
Secondly don't forget about cross site domain permission. Because I was testing from localhost:63532 and calling the REST service located on localhost:63002 they were not the same domain and was not being queried. For testing I needed to add the the following to the response header.
Access-Control-Allow-Origin:http://localhost:63532
These two items were the key to getting past the timeout error.
In the case of your code calling HTML, if you read the linked documentation above there is a section in there describing HTML Response Format. Here is the relevant text:
If the request specifies out:html, the response should be an HTML page defining an HTML table with the data. This is useful for debugging your code, because the browser can render your result in a readable format directly. You cannot send a query for an HTML response using the google.visualization.Query object. You must make a query for an HTML response using custom code, or by typing a URL similar to this one in your browser:
Since in your code you are trying to do this:
var query = new google.visualization.Query('http://www.ichoosewellness.com/chartapitest/data.htm?tqx=reqId:1;out:html');
It seems from the documentation that this is not supported by the query function.

Resources