MVC 3 Returning multiple Flot graphs - javascript

Thanks for reading. As I am ramping up to MVC, I am also getting more exposure to a lot of Javascript (which I am very weak in).
I have view that renders a list of data like below
<table>
<tr>
<th>heading 1</th>
<th>heading 2</th>
<th>heading 3</th>
<th>heading 4</th>
<th>chart</th>
</tr>
foreach(var item in Model)
{
<tr>
<td>#item.data1</td>
<td>#item.data2</td>
<td>#item.data3</td>
<td>#item.data4</td>
<td><div id="graphname"></div> </td>
</tr>
}
</table>
By following the example from here http://blog.simontimms.com/2009/06/bar-graphs-using-flot-and-aspnet-mvc.html, I can get the proper data. How can I use what I have learned from that link, and also be able to create/return multiple graphs
<div id="graphname"></div>
since it is referrenced by the id? Or is there better way to do this completely?

You will need to set a unique ID for each div.
You can do this in a few different ways. Cleanest would be to tie it to your data somehow, eg if each item's item.data1 is a unique value (like a primary key) you could do the following
<div id="#("graphname_" + item.data1>"
Or you could add an index inside the foreach and refer to that
int i = 0;
foreach(var item in Model)
{
<tr>
<td>#item.data1</td>
<td>#item.data2</td>
<td>#item.data3</td>
<td>#item.data4</td>
<td><div id="#(graphname + i)"></div> </td>
</tr>
++i;
}
From there it's just a matter of calling $.plot for each graph, referencing the required data and the correct div

Related

Cypress iterate table rows get specific element in cells

I'm trying to iterate through table rows and get each row which includes a specific value,
but it doesn't work for me.
I'm using .each() to iterate the rows and .within() on each $el,
inside that, I use cy.get('td').eq(1).contains('hello') but I the get assertion error:
Timed out retrying: Expected to find content: 'hello' within the element: <td> but never did.
when I console.log cy.get('td').eq(1) it yields the desired cell in each row and the test passes, so I don't understand why chaining .contains() doesn't work...
it('get element in table', () => {
cy.visit('http://localhost:3000/');
cy.get('tbody tr').each(($el) => {
cy.wrap($el).within(() => {
cy.get('td').eq(1).contains('hello') // contains() doesn't work
})
})
});
<table>
<thead>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February</td>
<td>hello</td>
<td>$80</td>
</tr>
<tr>
<td>$10</td>
<td>hello</td>
</tr>
</tbody>
</table>
should('have.text', text) should work
cy.get('td').eq(1).should('have.text', 'hello')
If there's whitespace around text, use contain.text
cy.get('td').eq(1).should('contain.text', 'hello')
The simple answer is: don't :)
To be more specific use html attribute selection instead. The convention is to have an attribute named data-cy. Furthermore, I discovered it convenient to have a data-cy-identifier for when selecting specific rows. Since I'm not sure what you're trying with your code, I'll use a similar example that can hopefully get you going:
<table data-cy="expences">
<tr>
<td data-cy="month">January</td>
<td data-cy="price">$100</td>
</tr>
<tr data-cy="discounted">
<td data-cy="month">Feburary</td>
<td data-cy="price">$80</td>
</tr>
<tr data-cy="discounted">
<td data-cy="month">March</td>
<td data-cy="price">$10</td>
</tr>
</table>
You can of course do all sorts of combinations of this, but now you can do more specific and useful selections, such as:
cy.get('[data-cy="expenses"]').find('[data-cy="discounted"]').find('[data-cy="price"]').should(...)
And similar. This is flexible, because it reflects the structure of your data, and not the presentation, so you can change this to a list or whatever later. It avoids selecting of volatile things, so it's also more robust. It also uses a hierarchy rather than overly specific selectors.
The idea of adding things like data-cy-identifier allows you to do selections by ID (you can propagate it using javascript, angular, vue or whatever you use) and then checking things like the contents of a row with logically related items.
Hope it can get you going. Also I can recommend reading: https://docs.cypress.io/guides/references/best-practices.html

Angularjs Table error

I am very new to the UI development. I am using the AngularJS. I am trying to print all my values in a table. For that I am using Angularjs table. I have a headers and each header has multiple values. For one header the value will change based on the header. Here is my code.
<div>
<table datatable="ng"
class="table table-striped table-bordered dt-responsive nowrap"
cellspacing="0" width="100%">
<thead>
<tr>
<th>Entity Name</th>
<th>Field Name</th>
<th>{{headerName}}</th>
<th>DataType</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="entity in metadata">
<td>{{ entity.entityName }}</td>
<td>{{ entity.fieldName }}</td>
<td ng-if="entity.fieldLength != 'undefined'">{{entity.fieldLength}}</td>
<td ng-if="entity.familyName != 'undefined'">{{entity.familyName}}</td>
<td><select data-ng-init="dataType = entity.dataTypeList[0]"
data-ng-model="dataType"
data-ng-options="dataType for dataType in entity.dataTypeList"
class="form-control"
ng-change="onChange(entity.entityName,entity.fieldName,entity.fieldLength,dataType)"></select></td>
</tr>
</tbody>
</table>
</div>
Here if we observe one of the header "{{headerName}}" and this corresponding value will change based on this header. This headerName has two values (Field Length and Family Name). I used "ng-if" for this. Here are the two statements.
<td ng-if="entity.fieldLength != 'undefined'">{{entity.fieldLength}}</td>
<td ng-if="entity.familyName != 'undefined'">{{entity.familyName}}</td>
But when I execute this code I am getting an extra "td" in the table. Here is the output (Attachment).
So "FamilyName" are placed under "DataType" td. How can adjust this one. Can any one help me on this.?
Thanks in advance,
Amar.T
Not sure if I exactly follow but Is it possible you have four columns in your header and potentially 5 columns in your actual table? Is this the problem... also what happens when you do the following to check for undefined?
<td ng-if="typeof(entity.fieldLength) !== 'undefined'">{{entity.fieldLength}}</td>
<td ng-if="typeof(entity.familyName) !== 'undefined'">{{entity.familyName}}</td>
but why not combine the logic like so, so a vaue is shown without the ng-if and the need for two HTML columns?
<td>{{entity.fieldLength || entity.familyName}}</td>
Perhaps, also if possible you can move that logic into your controller (service,etc) That would make it easier to test. I think the answer above is correct also.

JS: Compare two tables and generate new one based on the two

I'm trying to get better at JavaScript/jQuery, so I guess some basic table manipulation would nice to try out. However I can't seem to find a way to get started doing what I want to achieve.
Lets say e.g. I have two tables, and I want to compare data and generate a third table based on the data in the two first ones. Lets say it's about movies, and I have this list of users, and list of movies with a column of whom likes the movie. In the third on the fly generated table I want to collect these data and write out the movie with whom likes it.
users
<table id="table_1">
<tr>
<th>user ID</th>
<th>name</th>
<th>country</th>
</tr>
<tr><td>1</td>
<td>martin</td>a
<td>usa</td>
</tr>
<tr><td>2</td>
<td>james</td>
<td>france</td>
</tr>
</table>
movies
<table id="table_2">
<tr>
<th>movie id</th>
<th>name</th>
<th>users favorite (id)</th>
</tr>
<tr><td>2</td>
<td>the expendables</td>
<td>1</td>
</tr>
<tr><td>2</td>
<td>titanic</td>
<td>2, 1</td>
</tr>
</table>
results
<div id="table">
</div>
I have this fiddle: https://jsfiddle.net/fpeh6fna/
You could use jQuery each commands here, for example (just a section of the code you would want):
$('#table_1').children('tr').each(function() {
var row = [];
$(this).children('td').each(function() {
row.push($(this).text());
});
rows.push(row);
});

Adding Column to jQuery Datatables

I want to add a column to a jQuery Datatable. It will be used to contain a delete button for each row, like I have for another table. The button picture and class are specific in the php file that retrieves the table data from a database.
Simply adding a column to the html as the following breaks the javascript on the page:
<th>New Column</th>
I do not see anything in the aoColumnDefs settings that does anything to the added column. What code and where do I need to add or edit to accommodate the new column?
I am not the original developer behind the existing tables.
You can add one or more th from here like Revenue2
<table class="mws-table">
<thead>
<tr>
<th>Date</th>
<th>Transaction ID</th>
<th>Segment</th>
<th>Revenue</th>
</tr>
</thead>
<tbody id="transactions">
<tr>
<td class="trDate"></td>
<td class="transactionId"></td>
<td class="segment"></td>
<td class="revenue"></td>
</tr>
</tbody>
<tfoot>
<tr class="customFooterRow">
<th>Total</th>
<th></th>
<th></th>
<th align ="left" class="revenueTotal"></th>
</tr>
</tfoot>
</table>
You might have forgotten to add the column for the body as well and in cases where you have a "tfoot" you will need to add another column to it as well.

DataTables - Last column fixed width

The idea is this :
I have one jQuery that loads the DataTables, and I know that I can set the "aoColumns" : "sWidth" parameter to make one column fixed width and it's working.
The problem that I have is that I have a lot of tables, variable numbers of columns, and I need the LAST one to be fixed size, no matter what number that column is. Sometimes can be 3rd, sometimes can be 8th, sometimes can be 16th, does not matter.
Is even possible ?
No, I don't want to call datatable jQuery for each table, no I don't want to modify anything in the structure because it's working very well right now, just maybe add some class or parameters to the Javascript.
Structure your tables like this:
<table class="tableClass">
<colgroup>
<col></col>
<col></col>
<col></col>
</colgroup>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
</tbody>
</table>
That way, your jQuery will just need to do this:
$('.tableClass').each(function() {
var self = this;
$(self).find('col:last').css('background-color', 'red');
});
That jQuery will find the last column in each table with that class, and do whatever you want with that last class on each one. (I just used the background-color to test it out.)
If all you're doing is just setting the width, you might be able to get away with doing $(self).find('th:last'), but the <colgroup> and <col> is the "correct" way to go.

Categories

Resources