Below is the tabular structure for expand & collapse, i have done using table. Now i have used the below script for collapse & expand. But sometime i succeeded in expand & sometime don't.
What i did, when i got response from the api, i call this function :
$timeout(function (){
$scope.initExpandCollapse();
},1000);
$scope.initExpandCollapse = function () {
angular.element(document).on("click", ".table_exp", function(){
var TBODY = angular.element(this).parents(3);
if(TBODY.hasClass("open")){
TBODY.children("tr.expand-table-row").hide();
TBODY.removeClass("open");
return false;
}
TBODY.addClass("open");
TBODY.children("tr.expand-table-row").show();
});
}
If you guys, can help me out for this problem . Thanks.
CSS:
tr.expand-table-row {
display: none;
}
tr.expand-table-row.open {
display: initial;
}
Angular
$scope.expandCollapse = function expandCollapse (item) {
item.open = !item.open
}
HTML
<table>
<tbody>
<tr ng-repeat="item in items track by $index"">
<td ng-click="expandCollapse(item)">++++</td>
<td>
<table>
<tr ng-class="{'open': item.open}" class="expand-table-row open">
<td>{{item.name}}</td>
<td ng-repeat="data in item.options">{{data.name}}</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
You need nested tables so the click marker does not simply vanish with the rest, apart from that the salient point is the ng-class="{'open': item.open}" espression that sets the class open if the property open on item is set.
Try to use window.onload instead of $timeout, or add you script to the end of body tag.
Related
So I'm trying to create a table, where the table rows being divs that I've constructed from data that I get from my database.
I've seem to run into a issue.. I got this piece of javascript that starts running as soon as the page is ready, and it runs over and over again each 10 seconds. The purpose of this script is to update the partial view using ajax so that I don't have to refresh the browser to see changes in the table.
<script type="text/javascript">
$(document).ready(function () {
setInterval(CheckAvailability, 10000);
setTimeout
});
function CheckAvailability() {
$.ajax({
type: "POST",
url: "/Dashboard/CheckChange",
contentType: "application/json; charset=utf-8",
dataType: "json",
mimeType: "text/html",
success: function (response) {
if (response) {
$('#itemsss').load("/Dashboard/ReturnItems");
console.log("Updated!");
}
else {
console.log("Failed!");
}
}
});
};
</script>
This returns true every single time because it's something I've set explicitly.
It does load(); the content that this action returns though.
public IActionResult ReturnItems()
{
Items = new List<EbayProduct>();
using (var ctx = new UserContext())
{
Items = ctx.Users.Include(x => x.Items).Where(x => x.Username == "Admin").FirstOrDefault().Items;
}
return PartialView("_Item", Items);
//return null;
}
This is where I load the PartialView
<div id="itemsss">
<table id="foo-filtering" class="table table-bordered table-hover toggle-circle" data-page-size="7">
<thead>
</thead>
<tr>
<td>
<partial name="_Item" />
</td>
</tr>
<tfoot>
<tr>
<td colspan="5">
<div class="ft-right">
<ul class="pagination"></ul>
</div>
</td>
</tr>
</tfoot>
</table>
</div>
And this is what the actual PartialView looks like
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
<div class="container-1">
<div class="box-img">
<img src="#item.ProductImage" />
</div>
<div class="body">
<h3>#item.ItemName</h3>
<p>#item.SubTitle</p>
</div>
<div class="box-button">
<p>#item.SKU</p>
</div>
<div class="box-button">
<p class="mt-3 mr-2">$#item.Price</p>
<button class="btn btn-primary">Export</button>
</div>
</div>
</td>
</tr>
}
</tbody>
And here is where the issue occurs.. When I first load the page, it all works fine, it looks great and it works perfectly, but as soon as it does the first refresh.. Or .load();.. It suddenly stops working correctly, and by that I mean that it doesn't load any <tr> elements.
This is what the DOM looks like when I first load the page and it hasn't refreshed yet, each td contains the div with the class container-1 so it works just fine
And here is what it looks like after the first refresh and every single refresh after that
The jQuery call $('#itemsss').load("/Dashboard/ReturnItems") replaces existing content of the container with new elements - jQuery documentation states it as
.load() sets the HTML contents of the matched elements to the returned data.
Replacing the innerHTML of #itemsss wipes out the table element. Because <tbody>, <tr> and <td> tags are invalid outside a table, the parser ignores them, leaving #itemsss containing <div> elements only, as shown in the second picture.
If successful AJAX calls are intended to update the whole table the server could send complete HTML for the table, which could then be used to replace the content of #itemss, as shown in the post. Since picture 1 shows multiple tbody elements I assume this is not the case.
I tried appending tbody html to the table under different conditions: with or without a header and with or without existing table sections. Warning I am not a jQuery programmer - if useful, integrate and modify as best suited:
"use strict";
function appendTableBody( bodyHTML) {
let previous = $("#foo-filtering > tbody").last();
if( !previous.length) {
previous = $("#foo-table > thead").last();
}
if( previous.length) {
previous.after( bodyHTML);
}
else {
$("#foo-filtering").prepend( bodyHTML)
}
}
appendTableBody("<tbody><tr><td>appended section<\/td><\/tr><\/tbody>", true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- body-html -->
<table id="foo-filtering">
<thead>
<tr><th>Table Header</th></tr>
</thead>
<tbody>
<tr><td>Table section 1</td></tr>
</tbody>
<tbody>
<tr><td>Table section 2</td></tr>
</tbody>
<tfoot>
<tr><th>table footer</th></tr>
</tfoot>
</table>
I didn't try to replace an existing tbody element, but assume it would involve selecting the element and calling the .html() method.
I am new to Knockout JS, therefore need your help to fix one small issue. I am trying to bind css style with a table row in CSHTML page, based on a condition. I have added 2 rows but displaying only one for each item using 'visible' attribute. Following is my cshtml code:
<table class="listing">
<tbody class="no-wrap" data-bind="foreach: searchResultsListing.pagedItems, select: searchResultsListing">
<tr class="selectable" data-bind="visible: !$root.isMatchedCase($data), css: { selected: $root.searchResultsListing.isSelected($data) }">
<td class="check"><span></span></td>
--
--
<tr/>
<tr class="selectablematch" data-bind="visible: $root.isMatchedCase($data), css: { selected: $root.searchResultsListing.isSelected($data) }">
<td class="check"><span></span></td>
--
--
<tr/>
Underlying Typescript: Inside app.listing.ts File:
isSelected(item: T) {
return this.selectedItems.indexOf(item) >= 0;
}
As you can see, based on the result of isMatchedCase() method (which returns a boolean), I am displaying either of the tr (selectable or selectablematch). The problem is the css on the tr is getting binded only for the first tr, i.e. with the class selectable, and not getting binded with the selectablematch tr. The method 'isSelected($data)' is not getting called when the checkbox in the first td is clicked for 'selectablematch' tr. Can you guys please let me know what I am missing here?
I am little confused as to why you need to have 2 tr to begin with. What you could do is have a computed which would return the correct class for you and have only one row which will be always visible. Not need to deal with hide/show etc.
Look at this article on the css binding and how it is done. Here is what I am suggesting:
<table class="listing">
<tbody class="no-wrap" data-bind="foreach: searchResultsListing.pagedItems, select: searchResultsListing">
<tr data-bind="css: { rowClass($data), selected: $root.searchResultsListing.isSelected($data) }">
<td class="check"><span></span></td>
<tr/>
</tbody>
</table>
And your pureComputed (wrapped in a function so we can pass the $data):
var rowClass = function(data) {
return ko.pureComputed(function(){
return isMatchedCase(data) ? 'selectablematch' : 'selectable')
)}
}
I think that should get you going in the right direction.
I have a nested HTML table. I would like to show parts of the nested table depending on the header clicked using javascript
http://jsfiddle.net/TtWTR/103/
so far it shows all three parts. I want to click header A and show only optionA, click headerB and only show optionB etc etc. Not sure if ive set it up right as all three are showing. thanks
To achieve expected result, use below option oh hide() and show() methods
$('.trigger').click(function() {
console.log($(this).text())
var selectedHdr = $(this).text();
$('.nested tr').hide();
$('.nested tr#'+selectedHdr).show();
});
https://codepen.io/nagasai/pen/vdabJQ
Usually I find it convenient to use CSS class selectors on the "root" element (in your case that would be .toptable) allowing you to toggle it to show and hide child elements.
<table class="toptable">
<tr class="accordion">
<td class="A trigger">A</td>
<td class="B trigger">B</td>
<td class="C trigger">C</td>
</tr>
<tr>
<td>
<table>
<tr class="content A">
<!-- will toggle using show-A -->
</tr>
</table
</td>
</tr>
</table>
Then you can make sure to hide the .content rows using CSS unless specific classes are set on the top table:
.content {
display: none; /* content hidden by default */
}
.show-A .A.content {
display: table; /* show when the parent table has .show-A set */
}
Now you just have to add event listeners to your triggers to toggle the classes for the different content rows:
const toptable = document.querySelector('.toptable');
['A', 'B', 'C'].forEach((group) => {
const trigger = document.querySelector(`.${group}.trigger`);
trigger.addEventListener('click', () => {
toptable.classList.toggle(`show-${group}`);
});
});
This can be done using the following script
$('.nested').hide();
$('tr .trigger').click(function() {
var target_id= "#"+$(this).attr('id')+"-table";
$('.nested').not(target_id).hide();
$(target_id).show();
});
and is shown in http://jsfiddle.net/TtWTR/152/
I currently have the following piece of angular code:
function MyController($scope) {
var items = [];
$scope.addRow = function () {
items.push({ value: 'Hello, world!' });
$scope.items = items;
}
}
Along with the following snippet of html:
<table ng-controller="MyController">
<tr ng-repeat="item in items">
<td>
{{item.value}}
</td>
</tr>
<tr>
<td>
<button ng-click="addRow()">Add row</button>
</td>
</tr>
</table>
As expected, each time I click Add Row a new row is added with the text Hello, World!.
How can I extend this so that the newly added row glows or flashes as it appears for a brief moment? The idea being that in the real app the item will be added dynamically without a button click so I'd like to draw the users attention to the newly added item.
if you include the ng-animate module you can use css classes(the ngAnimate page also shows how to use in javascript)
http://docs.angularjs.org/api/ngAnimate
<tr ng-repeat="item in items" class="slide">
<td>
{{item.value}}
</td>
</tr>
<style type="text/css">
.slide.ng-enter, .slide.ng-leave {
-webkit-transition:0.5s linear all;
transition:0.5s linear all;
}
.slide.ng-enter { } /* starting animations for enter */
.slide.ng-enter-active { } /* terminal animations for enter */
.slide.ng-leave { } /* starting animations for leave */
.slide.ng-leave-active { } /* terminal animations for leave */
</style>
in the .ng-enter, .ng-leave classes you would specify the attribute you would want to animate, eg opacity,width,height etc
For triggering animations from javascript look for the JavaScript-defined Animations section of the ngAnimate page
For animation examples see http://www.nganimate.org
im not a great angular developer but i think you need to use the ngAnimate directive, and then use css transitions, here is an example from the oficial documentation
I have created two tables on my page. I want that when a user clicks on a table row, the data of that row is copied to another table.
<div class="processor">
<table id="proctable">
<tr class="header">
<th>Description</th>
<th>Price</th>
</tr>
<tr class="hover">
<td><span id="4770K">Intel Core i7 4770K 4TH GEN. 3.5GHZ 8MB CACHE MAX TURBO FREQUENCY 3.9GHZ</span></td>
<td>$320</td>
</tr>
<tr class="hover">
<td><span id="4771">Intel Core i7 4771 4TH GEN. 3.5GHZ 8MB CACHE MAX TURBO FREQUENCY 3.9GHZ</span></td>
<td>$290</td>
</tr>
<tr class="hover">
<td><span id="4770">Intel Core i7 4770 4TH GEN. 3.4GHZ 8MB CACHE MAX TURBO FREQUENCY 3.9GHZ</span></td>
<td>$280</td>
</tr>
<tr class="hover">
<td><span id="4771">Intel Core i5 4670K 4TH GEN. 3.4GHZ 6MB CACHE MAX TURBO FREQUENCY 3.8GHZ</span></td>
<td>$240</td>
</tr>
</table>
<div id="aside">
<table id="comptable">
<tr class="header">
<th>Product</th>
<th>Price</th>
</tr>
</table>
</div>
I have searched for any help I may find but could not get any specific answer.
Here is the link to the code on jsfiddle
http://jsfiddle.net/jibranjb/LzgNd/#&togetherjs=fcgCI5QRn8
I am fairly new to Javascript and jQuery so please consider that.
Not sure what you wanted exactly. But if you want to store the data you can store it using arrays. ( you can use any data structure, I am using them as they are simple)
Check the below code, I am using items array, to store the selected row. On clicking the Add to List button, the selected tr will be added to the array and it will be display in the respective table.
var items = [];
$(".addBtn").on("click", function() {
var newTr = $(this).closest("tr").clone();
items.push(newTr);
newTr.appendTo( $("#comptable") );
});
I have added the Add to List button, the updated html markup would be;
<td>
<input class="addBtn" type="button" value="Add to List">
</td>
Updated Fiddle Demo
add this script ( using Jquery)
$('#proctable tr.hover').unbind('click').click(function(){
$(this).clone().appendTo('#comptable');
return false;
})
http://jsfiddle.net/4qFgX/3/
I will suggest this:
$('#proctable tr.hover').click(function () {
var x = $(this)[0].outerHTML
$('#comptable').append(x);
});
Something like this ?
$(function() { // when dom is ready
$('#proctable tr.hover a').on('click', function(e) { // when you click on a link
var row = $(this).parents('tr').eq(0); // you get the direct parent of the current clicked element
$('#comptable').append(row); // you append this parent row in the other table
e.preventDefault(); // your prevent the default link action
});
});
http://jsfiddle.net/LzgNd/1/