jQuery selectable list with nested table not sized properly in jQuery tab - asp.net-mvc-3

I'm implementing a jQuery tab in my MVC3 application, but one of the tabs is not sized properly. That is, some of the content is inside the tab, but the following strange formatting on my part is only partially inside the tab:
<div id="tabs">
<ul>
<li>Edit Schedule</li>
...
</ul>
<div id="tabs-1">
...
<div id = "scheduleData">
#Html.Partial("_partialView", ViewData["data"])
</div>
</div>
...
</div>
My partial view renders many tables, one with just a head, and the rest nested inside a jQuery selectable list:
<table>
<thead>
<tr>
<td>ID</td>
...
</tr>
</thead>
</table>
<ol id="selectable>
#foreach (var obj in Model)
{
<li class="ui-widget-content">
<table>
<tr>
<td>#obj.ID</td>
...
</tr>
</table>
</li>
}
</ol>
I'm not sure whether the tab sizing problem is happening because of the partial view, or my very strange formatting, or both.
It is worth noting that only the first table is inside the tab, and any other tables are consistently not in the tab, no matter how large or small the partial view is.
This is obviously a sloppy solution, and I was wondering if there is a better way to render a table row inside a selectable list so the jQuery tab is sized correctly, such as having all the rows in the first table? (which won't work because you can't nest a selectable list inside a table, to my knowledge) I appreciate your input.

The possibility exists to make a table a selectable item, instead of each row, but due to formatting issues I adopted the following solution instead:
$(document).ready(function () {
$("#scheduleTable tr").click(function () {
var href = $(this).find("a").attr("href");
if (href) {
$("#editDialog").dialog({ modal: true });
}
});
});
The markup then has an edit link in each row, which the Javascript watches, then creates a jQuery dialog box.
<table>
<thead>
<th> </th>
...
</thead>
<tbody>
#foreach (var obj in Model)
{
<tr>
<td>Edit</td>
...
</tr>
}
</tbody>
</table>
<div id="editDialog" title="Edit Entry" style="display:none">
...
</div>

Related

Unable to click on Select link present in last column of web table

I want to search Seller and have to click on select link for selected one. When I type seller name, it shows only record for selected seller.
I tried with following code, its not working. Can anyone please help
cy.get('input[name="search"]',{ timeout: 10000 }).type(this.data1.vehicle1_seller1)
//cy.wait(6000)
Cypress.config('defaultCommandTimeout', 10000);
cy.get('td[class="span-3"] div').each(($el, index, $list) => {
if ($el.text().includes('STB002')) {
// cy.contains("Select").eq(index).click()
cy.get('.span-1-5 > div > a > span').contains('select').eq(index).click({force:true})
}
}
this is the DOM structure >
<table>
<tbody>
<tr class="even">
<td class="span-3">
<div title="06V001">06V001</div> == $0
</td>
<td>
<div title="06 Vauxhall Ormskirk">06 Vauxhall Ormskirk</div>
</td>
<td class="span-1-5">
<div>
<a id="link57" href="./wicket/page?7-1.-seller-table-body-rows-10-cells-3-cell-link">
<span>select</span>
</a>
</div>
</td>
</tr>
<tr class="odd">
</tr>
<tr class="even">
</tr>
</tbody>
</table>
The HTML table is set out in rows and cells, exactly as you see it on the screen.
Your test is searching for the cell containing the text, but really you want to search for the row containing the text, then get the select button of that row.
The basic test would be
cy.contains('tr', 'STB002')
.within(() => {
// now inside the row
cy.contains('span', 'select').click()
})
The next problem is the car STB002 isn't on the first page, so you won't find it straight after loading.
Maybe use the search box to load that row (as you have in one screen-shot). I can't say what that code is, because the DOM picture doesn't include the search box.

Passing computed string to x-teleport in alpine.js

I want to append an element to a specific element when the user clicks the button. The scenario goes like this. Is there another way to deal with that kind of problem?
<table>
<tbody>
<tr>
<td>
One
<button>delete</button>
<button x-on:click="edit(passIdToFunc)">edit</button>
</td>
</tr>
<tr id="one" style="display: hidden"></tr>
<!-- append x-teleport dom node to here when current value is id = one -->
<tr>Two</tr>
<tr id="two" style="display: hidden"></tr>
<tr>Three</tr>
<tr id="three" style="display: hidden"></tr>
...
</tbody>
</table>
<!--
For the initial render, or if there is no table data,
I would like to append it to somewhere else with display none.
-->
<template x-teleport="computedString">
...
</template>
This looks like the wrong usage for x-teleport, though it's not clear from the example where you are teleporting to. You can just use x-show to toggle display:none if that's what you're looking for.

Angular 2 doesn't update my view after I add or edit item

I've finally made my app in angular 2. Everything is solved, except one thing. When I add item into my table or edited it, I can't see the change until I refresh page or click for example next page button (I have implemented pagination). I included:
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
in this order. My method for adding item is very simple:
addDepartment(item){
this._departmentService.addDepartment(item)
.subscribe(departments => this.department = departments.json());
this.getAll();}
Whhen I add item, and put breakpoint on get method, It is called correctly and I get right information from my DB, but I don't know why view isn't refreshed then. Do you have any idea why is it happened? Thanks for suggestions!
EDIT: department is just department: Department, where Department is interface with properties (departmentNo, departmentName, departmentLocation). The view for adding item looks like:
<form [ngFormModel]="myForm"
(ngSubmit)="addDepartment(newItem); showAddView=false" [hidden]="!showAddView" align="center">
<div>
<label for="editAbrv">Department name:</label><br>
<input type="text" [(ngModel)]="newItem.departmentName" [ngFormControl]="myForm.controls['departmentName']" >
<div *ngIf="myForm.controls['departmentName'].hasError('required')" class="ui error message"><b style="color:red;">Name is required</b></div>
</div>
<br/>
<div>
<label for="editAbrv">Department Location:</label><br>
<input type="text" [(ngModel)]="newItem.departmentLocation" [ngFormControl]="myForm.controls['departmentLocation']" >
<div *ngIf="myForm.controls['departmentLocation'].hasError('required')" class="ui error message"><b style="color:red;">Location is required</b></div>
</div>
<br/>
<div>
<button type="submit" [disabled]="!myForm.valid" class="ui button">Add item</button>
<button><a href="javascript:void(0);" (click)="showHide($event)" >
Cancel
</a></button>
</div>
</form>
and my department table is:
<table align="center">
<thead>
<tr>
<td>#</td>
<td><strong>Department</strong></td>
<td><strong>Department Location</strong></td>
<td><strong>Edit</strong></td>
<td><strong>Delete</strong></td>
</tr>
</thead>
<tbody>
<tr *ngFor="#department of departments | searchString:filter.value ; #i = index">
<td>{{i + 1}}.</td>
<td> {{department.departmentName}}</td>
<td>{{department.departmentLocation}}</td>
<td>
<button class="btnEdit" (click)="showEdit(department)">Edit</button>
</td>
<td>
<button class="btnDelete" (click)="deleteDepartment(department)" >Delete</button>
</td>
</tr>
</tbody>
</table>
With this code, you don't wait for the response of the addDepartment request and execute the getAll request directly.
addDepartment(item){
this._departmentService.addDepartment(item)
.subscribe(departments => this.department = departments.json());
this.getAll();
}
You should move the call to getAll within the callback registered in subscribe. At this moment, the addDepartment is actually done and you can reload the list...
The code could be refactored like this (it's a guess since I haven't the content of addDepartment and getAll methods):
addDepartment(item){
this._departmentService.addDepartment(item)
.subscribe(addedDepartment => {
this.department = this.getAll();
});
}
This issue occurs because of the way you're using departmant and how change detection works. When you use *ngFor="#department of departments", angular change detection looks for a object reference on departments array. When you update/change one of the items in this array object reference to the array itself doesn't change, so angular doesn't run change detection.
You have few options:
1) change reference of the array by replacing it with new array with updated values
2) tell angular explicitly to run change detection (which I think is easier in your case):
constructor(private _cdRef: ChangeDetectorRef) {...}
addDepartment(item){
this._departmentService.addDepartment(item)
.subscribe(departments => this.department = departments.json());
this.getAll();
this._cdRef.markForCheck();
}

Using a partial view to represent a table row

I am trying to use a partial view to represent rows of a table in my project. I currently have
<table>
<thead>
<tr>
<th >
Column 1
</th>
<th >
Column 2
</th>
<th >
Column 3
</th>
</tr>
</thead>
<tbody>
#foreach(var item in Model.Items)
{
#Html.Action("ItemCalculatedView", new { Id = item.Id})
}
</tbody>
</table>
In my partial view I have this
#using (Ajax.BeginForm("SaveStuff", "Whatever",
new { id = #Model.Id }, new AjaxOptions()
{
HttpMethod = "Post",
OnSuccess = "Success"
}))
{
#Html.HiddenFor(m => m.Id)
<tr>
<td>
#Html.Label("Col1", Model.Col1)
</td>
<td>
#Html.TextBox("Number", Model.Number)
</td>
<td>
<input type="submit" id='submit-#Model.Id'/>
</td>
</tr>
}
How can I make this work?
You can put a form inside a table cell, but you can't have the form inside a tbody element, or spanning multiple columns. So there are three options:
Use a CSS layout instead of a table, or use divs with CSS display set to "table". (for example)
Put the entire form (TextBox and Submit) inside a td
Put another table inside the td element
I'd recommend #1 -- use a CSS layout to construct the table, since it's difficult to style table tags:
Main
<div class="table">
<div class="header-row">
<div class="header-cell">Column 1</th>
<div class="header-cell">Column 2</th>
<div class="header-cell">Column 3</th>
</div>
#foreach(var item in Model.Items)
{
#Html.Action("ItemCalculatedView", new { Id = item.Id})
}
</div>
Partial
#using (Ajax.BeginForm(
actionName: "SaveStuff",
controllerName: "Whatever",
routeValues: new { id = #Model.Id },
ajaxOptions: new AjaxOptions
{
HttpMethod = "Post",
OnSuccess = "Success"
},
htmlAttributes: new { #class = "row" }
))
{
<div class="cell">
#Html.HiddenFor(m => m.Id)
</div>
<div class="cell">
#Html.Label("Col1", Model.Col1)
</div>
<div class="cell">
#Html.TextBox("Number", Model.Number)
</div>
<div class="cell">
<input type="submit" id='submit-#Model.Id'/>
</div>
}
CSS
.table { display: table; }
.header-row, row { display: table-row; }
.header-cell, cell { display: table-cell; }
You have several issues here. First, as dbaseman mentions, you can't place forms within the structure of a table and have it be legal HTML. It may work, or it might not, and even if it does work, you can't guarantee it will continue to work.
I would instead wrap your table in the form, and then on the post figure out which button was pressed based on its value and/or index.
I would strongly advise against using css tables for tabular data. It's just not semantically correct.
Another possible solution is, instead of using the Ajax.BeginForm, instead use jQuery $.ajax and then you can select a row of data in javascript to post to the server.

Dojo Table not Rendering in IE6

I'm trying to use Dojo (1.3) checkBoxes to make columns appear/hide in a Dojo Grid that's displayed below the checkBoxes. I got that functionality to work fine, but I wanted to organize my checkBoxes a little better. So I tried putting them in a table. My dojo.addOnLoad function looks like this:
dojo.addOnLoad(function(){
var checkBoxes = [];
var container = dojo.byId('checkBoxContainer');
var table = dojo.doc.createElement("table");
var row1= dojo.doc.createElement("tr");
var row2= dojo.doc.createElement("tr");
var row3= dojo.doc.createElement("tr");
dojo.forEach(grid.layout.cells, function(cell, index){
//Add a new "td" element to one of the three rows
});
dojo.place(addRow, table);
dojo.place(removeRow, table);
dojo.place(findReplaceRow, table);
dojo.place(table, container);
});
What's frustrating is:
Using the Dojo debugger I can see that the HTML is being properly generated for the table.
I can take that HTML and put just the table in an empty HTML file and it renders the checkBoxes in the table just fine.
The page renders correctly in Firefox, just not IE6.
The HTML that is being generated looks like so:
<div id="checkBoxContainer">
<table>
<tr>
<td>
<div class="dijitReset dijitInline dijitCheckBox"
role="presentation" widgetid="dijit_form_CheckBox_0"
wairole="presentation">
<input class="dijitReset dijitCheckBoxInput"
id="dijit_form_CheckBox_0"
tabindex="0" type="checkbox"
name="" dojoattachevent=
"onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick"
dojoattachpoint="focusNode" unselectable="on"
aria-pressed="false"/>
</div>
<label for="dijit_form_CheckBox_0">
Column 1
</label>
</td>
<td>
<div class="dijitReset dijitInline dijitCheckBox"
role="presentation" widgetid="dijit_form_CheckBox_1"
wairole="presentation">
<input class="dijitReset dijitCheckBoxInput"
id="dijit_form_CheckBox_1"
tabindex="0" type="checkbox"
name="" dojoattachevent=
"onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick"
dojoattachpoint="focusNode" unselectable="on"
aria-pressed="false"/>
</div>
</td>
</tr>
<tr>
...
</tr>
</table>
</div>
I would have posted to the official DOJO forums, but it says they're deprecated and they're using a mailing list now. They said if a mailing list doesn't work for you, use StackOverflow.com. So, here I am!
It looks like you forgot to create a <tbody> element.
I also encountered this issue when trying to generate a table using dojo in IE7. The html is there but nothing is rendered. Again, the solution is to use thead, tbody tags.

Resources