On 'click' not firing/finding Datatable child row to open up - javascript

Here's all the code.
#model IEnumerable<Arb.Models.Fixture>
#{
ViewBag.Title = "Fixtures";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<table id="fixtures" class="table table-bordered table-hover">
<thead>
<tr>
<th></th>
<th>Fixture</th>
<th>Date/Time</th>
<th>Market</th>
<th>Selection</th>
<th>Bookie</th>
<th>Coupon</th>
<th>Back</th>
<th>Lay</th>
<th>Size</th>
<th>Percent</th>
</tr>
</thead>
<tbody></tbody>
</table>
#section scripts
{
<style type="text/css" class="init">
td.details-control {
background: url('http://next.datatables.net/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('http://next.datatables.net/examples/resources/details_close.png') no-repeat center center;
}
</style>
<script>
/* Formatting function for row details - modify as you need */
function format(d) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<tr>' +
'<td>Full name:</td>' +
'<td>' + d.name + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extension number:</td>' +
'<td>' + d.extn + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extra info:</td>' +
'<td>And any further details here (images etc)...</td>' +
'</tr>' +
'</table>';
}
$(document).ready(function () {
var fixtureTable = $('#fixtures').DataTable({
ajax: {
url: "/api/fixtures",
dataSrc: ""
},
columns: [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{
data: "eventName",
render: function (data, type, fixture) {
return "<a href='/fixtures/edit/" + fixture.id + "'>" + fixture.eventName + "</a>";
}
},
{
data: 'eventDateTime',
render: function (data, type, row) {
var d = new Date(data);
return d.getDate() + '-' + ('0' + d.getMonth()).slice(-2) + ' ' + ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2);
}
},
{ data: 'marketName' },
{ data: 'selectionName' },
{ data: 'bookmakerName' },
{ data: 'couponName' },
{
data: 'backOdds',
render: $.fn.dataTable.render.number(',', '.', 2)
},
{
data: 'exchangeType.layOdds',
render: $.fn.dataTable.render.number(',', '.', 2)
},
{
data: 'exchangeType.size',
render: $.fn.dataTable.render.number('', '.', 0, '£')
},
{
data: null,
render: function (data, type, row) {
return Math.round((row.backOdds / row.exchangeType.layOdds) * 100 - 100) + '%';
}
}
],
"order": [[1, 'asc']]
});
setInterval(function () {
fixtureTable.ajax.reload(null, false); // user paging is not reset on reload
var currentTime = new Date().toLocaleTimeString('en-GB', {
hour: "numeric",
minute: "numeric",
second: "numeric"
});
var currentDate = new Date();
var datetime = "Last Updated: " + currentDate.getDate() + "/" + (currentDate.getMonth() + 1)
+ "/" + currentDate.getFullYear() + " " + currentTime;
$("#UpdateTime").text(datetime);
}, 10000);
// Add event listener for opening and closing details
$('#fixtures tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
}
});
});
</script>
}
One thing I have noticed is that sometimes but not always it is showing "selector td.details-control is already specified earlier". But when I look for any earlier definitions including global searching or commenting out code - the error still appears.
IDK, if this is a red herring, but, it's not getting the child row somehow.
This is what I am trying to achieve https://datatables.net/examples/api/row_details.html

I see that following could be mistakes:
with ajax update - you tbody will be recreated, so your event will not work (try to use $('#fixtures').on('click', 'tbody td.details-control', ...
var row = table.row(tr); - should be var row = fixtureTable.row(tr);

Related

jQuery fresh ALL rows from PHP loop

Im not sure what is happening here, but I can not update this DIV per every row using this code. This code loads a initial user list, and loads the rest (after first 3) to a DIV dropdown triggered by click event.
<? foreach ($res as $row) { ?>
<script>
function fetchIndexUsers() {
$(function () {});
$.ajax({
url: '/ajax/ajax_live_index_users.php',
method: 'GET',
cache: false,
dataType: 'JSON',
data: {
item_id: <?=intval($row["item_id"])?>
},
success: function (data) {
var html_to_append = '';
array = [];
results = [];
$.each(data, function (i, item) {
results[i] = data[i];
array[0] = item.total;
array[1] = item.calc;
let icon = item.user.match(/(^|\W)yes($|\W)/i) ? 'arrow_upward' : 'arrow_downward';
html_to_append += '<div style="display:inline;float:left"><span class="material-icons" style="vertical-align:top;width:16px;padding-right:30px;color:#c0c0c0">' + icon + '</span></div><div style="display:inline;float:left;padding-bottom:1px"><a class="tooltip-newusers" title="' + item.username + '" href="/user/?id=' + item.user_id + '"><img style="box-shadow:2px 2px 10px #D3D3D3;height:35px;width:35px;border-radius:50%;margin-bottom:6px;margin-right:-20px;margin-top:-5px;vertical-align:middle;position:relative;z-index:10005;border:2px solid #FFF" src="/' + item.avatar + '" /></a></div><div style="clear:both"></div>';
return i <= 3;
});
if (array[0] >= 3) {
$("#live-peers-more-<?=intval($row["item_id"])?>").html('<div id="slidedown-<?=intval($row["item_id"])?>" style="user-select:none;margin-top:-14px;position:absolute;right:-20px;font-size:13px;background:purple;padding:0 6px;text-align:center;border-radius:3px;color:#FFF;font-weight:500;text-decoration:none;text-shadow:0 1px 1px rgba(0,0,0,.3);box-shadow:2px 2px 10px #D3D3D3"><a style="color:#fff;cursor:pointer">+ ' + (array.length - array[1]) + (array[1] >= 2 ? ' peers' : ' peer') + '</a></div>')
if (array[1] === 0) {
$("#live-users-more-<?=intval($row["item_id"])?>").hide();
}
}
$("#live-users-<?=intval($row["item_id"])?>").html(html_to_append);
$('.tooltip-newusers').tooltipster({
animation: 'grow',
delay: 200,
interactive: true,
theme: 'tooltipster-punk'
});
$("#live-peers-<?=intval($row["item_id"])?>").css('background', 'none');
$("#slidedown-<?=intval($row["item_id"])?>").html('<span><a style="color:#fff;cursor:pointer">+ ' + array[0] + (array[0] >= 2 ? ' peers' : ' peer') + '</a></span>');
}
});
$("#live-users-more-<?=intval($row["item_id"])?>").click(function () {
$("#slidedown-<?=intval($row["item_id"])?>").css('z-index', '9999999');
$.ajax({
url: '/ajax/ajax_live_index_users.php',
method: 'GET',
cache: false,
dataType: 'JSON',
data: {
item_id: <?=intval($row["item_id"])?>,
more: 1
},
success: function (data) {
var html_to_append = '';
$.each(results, function (i, item) {
html_to_append += '<div id="more_users" style="padding:6px;text-shadow:0 1px 1px rgba(0,0,0,.3)"><div id="peer-username">' + truncateString(item.username, 6) + '</div><a class="tooltip-newusers" title="' + item.username + '" href="/user/?id=' + item.user_id + '"><img style="height:35px;width:35px;border-radius:50%;border:2px solid #FFF" src="/' + item.avatar + '" /></a><div style="font-size:11px;font-weight:normal">' + formatBytesSpeed(item.totalspeed) + '</div></div>';
$("#slidedown-<?=intval($row["item_id"])?>").css('height', 'auto');
});
$("#slidedown-<?=intval($row["item_id"])?>").html(html_to_append);
$('.tooltip-newusers').tooltipster({
animation: 'grow',
delay: 200,
interactive: true,
theme: 'tooltipster-punk'
});
}
});
});
}
fetchIndexUsers();
setInterval(function () {
fetchIndexUsers()
}, 5000);
</script>
<div id="live-users-<?=intval($row["item_id"])?>" style="padding:10px;background:url(/images/loading-ellipsis.svg) no-repeat left">
<span style="padding-right:89px"></span>
</div>
<div id="live-users-more-<?=intval($row["item_id"])?>"></div>
<? } ?>
But any action coming back only updates the last row in from the array (PHP foreach array, with the JS emedded in the loop picking up on the ID from the iteration).
How come it only interacts with the last row? How can I update all rows since I am using a unique ID?
Thank you
You need to move the script out from the loop completely. Have ONE version of the script that delegates like this
$("#container").on("click", ".live-users-more",function () {
const item_id = $(this).prev().attr("id"); ....
and then change
<div id="live-users-more-<?=intval($row["item_id"])?>"></div>
to
<div class="live-users-more"></div>
where you have a
<div id="container"></div>
that wraps all the live user divs

I have javascript code to view a news from RSS as a vertical list. I need help to move the list of topics as horizontal one by one, in one line

I have javascript code to view a news from RSS as a vertical list.
(function ($) {
$.fn.FeedEk = function (opt) {
var def = $.extend({
MaxCount: 5,
ShowDesc: true,
ShowPubDate: true,
DescCharacterLimit: 0,
TitleLinkTarget: "_blank",
DateFormat: "",
DateFormatLang:"en"
}, opt);
var id = $(this).attr("id"), i, s = "", dt;
$("#" + id).empty();
if (def.FeedUrl == undefined) return;
$("#" + id).append('<img src="loader.gif" />');
var YQLstr = 'SELECT channel.item FROM feednormalizer WHERE output="rss_2.0" AND url ="' + def.FeedUrl + '" LIMIT ' + def.MaxCount;
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql?q=" + encodeURIComponent(YQLstr) + "&format=json&diagnostics=false&callback=?",
dataType: "json",
success: function (data) {
$("#" + id).empty();
if (!(data.query.results.rss instanceof Array)) {
data.query.results.rss = [data.query.results.rss];
}
$.each(data.query.results.rss, function (e, itm) {
s += '<li><div class="itemTitle"><a href="' + itm.channel.item.link + '" target="' + def.TitleLinkTarget + '" >' + itm.channel.item.title + '</a></div>';
if (def.ShowPubDate){
dt = new Date(itm.channel.item.pubDate);
s += '<div class="itemDate">';
if ($.trim(def.DateFormat).length > 0) {
try {
moment.lang(def.DateFormatLang);
s += moment(dt).format(def.DateFormat);
}
catch (e){s += dt.toLocaleDateString();}
}
else {
s += dt.toLocaleDateString();
}
s += '</div>';
}
if (def.ShowDesc) {
s += '<div class="itemContent">';
if (def.DescCharacterLimit > 0 && itm.channel.item.description.length > def.DescCharacterLimit) {
s += itm.channel.item.description.substring(0, def.DescCharacterLimit) + '...';
}
else {
s += itm.channel.item.description;
}
s += '</div>';
}
});
$("#" + id).append('<ul class="feedEkList">' + s + '</ul>');
}
});
};
})(jQuery);
I need help to move the list of topics as horizontal one by one, in one line. by used javascript code. this code display just 5 topics, which I need it, but I have problem to how can I movement it as horizontal.

Is there a setting to stop the display of "No data available in table" in the DataTable?

Initially my table has no data and I get "No data available in table" which is the expected functionality.
I'd like to have no text or row created as I will be populating the table via Ajax depending on user action.
Is there a setting to stop the display of this row in the table? I can't seem to find one. This code works but the first row reads "No data available in table". This is the jQuery code:
$.ajax({
type: 'GET',
url: '/Home/postInformationofConferenceTitle',
dataType: "JSON",
success: function (data) {
$.post("/Home/selectRooms", { xtitle: data.xglobalTitle }, function (data) {
var ndx = 0;
$.each(data.xroom_name, function (key, value) {
var Xroom_name = data.xroom_name[ndx];
var Xroom_plan = data.xroom_plan[ndx];
var column =
('<tr>' +
'<td>' +
'<div class="img-container">' +
'<img src="../../assets/img/room-plan/' + Xroom_plan + '" alt="..." id="imgsrc">' +
'</div>' +
'</td>' +
'<td id="imgname">' + Xroom_name + '</td>' +
'<td class="text-right">' +
'<i class="fa fa-edit"></i>' +
'</i>' +
'</td>' +
'</tr>');
document.getElementById('colmn').innerHTML = document.getElementById('colmn').innerHTML + column;
ndx++;
});
});
}
})
I guess you might be looking at the language settings of datatables.
language : {
"zeroRecords": " "
},
(Note the space between " ". (Its a hack but found it to be useful for now.)
$(document).ready(function () {
var serverData = [
]
var table = $('#example').DataTable({
language : {
"zeroRecords": " "
},
data: serverData,
columns: [
{ data: "name" },
{ data: "age" },
{ data: "isActive" },
{ data: "friends" },
],
'columnDefs': [{
'targets': 2,
'render': function (data, type, full, meta) {
let checked = ''
if (data) {
return '<input type="checkbox" checked / >';
}
else {
return '<input type="checkbox" / >';
}
return data;
}
},
{
'targets': 3,
"render": function (data, type, full, meta) {
var selectInitial = "<select>";
var selectClosing = "</select>";
var options = '';
$.each(data, function (key, value) {
options = options+"<option value="+value.id+">"+value.name+"</option>";
});
return selectInitial+options+selectClosing;
}
}
],
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='https://cdn.datatables.net/1.10.9/js/jquery.dataTables.min.js'></script><link rel='stylesheet prefetch' href='https://cdn.datatables.net/1.10.9/css/jquery.dataTables.css'>
<table id="example" class="display" width="100%" cellspacing="0">
<thead>
<tr>
<th>name</th>
<th>age</th>
<th>isActive</th>
<th>friends</th>
</tr>
</thead>
</table>
It works for me.
var someTableDT = $("#some-table").on("draw.dt", function () {
$(this).find(".dataTables_empty").parents('tbody').empty();
}).DataTable(/*init object*/);
Below worked for me:
$(document).ready(function () {
$("#TABLE_ID").DataTable();
$(".dataTables_empty").empty();
});
Next CSS worked for me to totally hide that block (not only delete text):
.dataTables_empty
{
display:none;
}

How to access via jquery to select controls created dynamically

I have created dynamically some select controls(a.k.a. groupbox) but every time that I try to access to one of them if get the followig error:
Uncaught TypeError: undefined is not a function
Here is the code:
var method =$("#slt" + (parseInt(buttonElementId + 1))).children("option").is("selected").text();
Where parseInt(buttonElementId + 1 is always a number so the error is not there
<html>
<head lang="en">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <!-- load bootstrap css -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <!-- load fontawesome -->
<style>
body { padding-top:80px; }
html, body, #wrapper
{
width: 100%;
height: 100%;
}
</style>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div class="container">
<div id="information"></div>
<div id="tableInformation"></div>
<div id="goBack"></div>
<br/>
<div id="inputDiv"></div>
<br/>
<br/>
<div id="UserGuide"></div>
</div>
<script src="js/jquery-1.11.js"> </script>
<script>
var apiUrl = 'http://localhost/devices';
$( document ).ready(function() {
// Handler for .ready() called.
jsonGETRequest(apiUrl, jsonExampleData);
});
$(document).on('click', ':button' , function() {
// reference clicked button via: $(this)
$("#UserGuide").empty();
var buttonElementId = $(this).attr('id');
if(buttonElementId.indexOf("btnShowFunc") > -1) {
buttonElementId = buttonElementId.replace("btnShowFunc","");
deviceUID = document.getElementById("mytable").rows[(parseInt(buttonElementId) + 1)].cells[1].innerHTML;
goBack = "firstAPIRequest";
$("#tableInformation tbody").remove();
jsonGETRequest(apiUrl + "/" + deviceUID + "/functions", jsonExampleDataFunctions);
} else if(buttonElementId.indexOf("btnGoBack") > -1 ) {
switch (goBack) {
case "firstAPIRequest":
goBack = "";
$("#tableInformation tbody").remove();
jsonGETRequest(apiUrl, jsonExampleData);
removeGoBackInputDiv();
break;
case "secondAPIRequest":
goBack = "firstAPIRequest";
$("#tableInformation tbody").remove();
jsonGETRequest(apiUrl + "/" + deviceUID + "/functions", jsonExampleDataFunctions);
removeGoBackInputDiv();
break;
}
}else if(buttonElementId.indexOf("btnRunFunc") > -1) {
goBack = "secondAPIRequest";
buttonElementId = buttonElementId.replace("btnRunFunc","");
var functionUID = document.getElementById("mytable").rows[(parseInt(buttonElementId) +1)].cells[2].innerHTML;
var method =$("#slt" + (parseInt(buttonElementId + 1))).children("option").is("selected").text();
$("#tableInformation tbody").remove();
$("#inputDiv").empty();
// /jsonPOST(apiUrl '/functions/' + functionUID )
}
});
function loadDataIntoDeviceGrid(jsonData) {
//$("#tableInformation").addClass("table table-responsive table-bordered");
var tbl=$("<table/>").attr("id","mytable");
$("#tableInformation").append(tbl);
$("#mytable").append("<tr>" + "<th>dal.device.status</th>" + "<th>dal.device.UID</th>"
+ "<th>dal.device.driver</th>" + "<th>service.id</th>" +"<th></th>" + "</tr>");
for(var i=0;i<jsonData.length;i++)
{
var tr = "<tr>";
var td1 = "<td>"+jsonData[i]["dal.device.status"]+"</td>";
var td2 = "<td>"+jsonData[i]["dal.device.UID"]+"</td>";
var td3 = "<td>"+jsonData[i]["dal.device.driver"]+"</td>";
var td4 = "<td>"+jsonData[i]["service.id"]+"</td>";
//#Deprecated var dataList = fillSelectControl(jsonData[i]["objectClass"]); #Deprecated
var btn = "<td>" + "<button id='btnShowFunc"+ i + "' class='btn btn-success btn-lg'>See function</button>" + "</td></tr>";
$("#mytable").append(tr + td1 + td2 + td3 + td4 + btn );
}
$("#mytable").addClass("table table-responsive table-bordered");
}
function loadInformationDeviceGrid() {
$("#UserGuide").addClass("alert alert-info");
$("#UserGuide").html("<h3>Getting devices list:</h3><br/> "+
"Using this request, you can retrieve a list of all the available devices."+
"For every device, among other info, there is the indication of the device unique ID, which" +
"can be used to directly access to the device and the indication of the device driver (ZigBee, Bluetooth, etc.).<br/>If you want see some request response example please visit this <a href='#'>site</a>");
}
function removeGoBackInputDiv() {
$("#inputDiv").empty();
$("#btnGoBack").remove();
}
function loadDataIntoFunctionsGrid(jsonData) {
$("#mytable").append("<tr>" + "<th>function.device.UID</th>"
+ "<th>service.id</th>" + "<th>function.UID</th>" + "<th>operation.names</th>" + "<th></th>" + "</tr>");
var tr, td2, td3, td4, dt2, btn;
for(var i = 0; i < jsonData.length; i++) {
tr = "<tr>";
//#Deprecated td1 = "<td>" + jsonData[i]["CLASS"] + "</td>";
td2 = "<td>" + jsonData[i]["al.function.device.UID"] + "</td>";
td3 = "<td>" + jsonData[i]["service.id"] + "</td>";
td4 = "<td>" + jsonData[i]["dal.function.UID"] + "</td>";
//#Deprecated dt1 = fillSelectControl(jsonData[i]["objectClass"]);
dt2 = fillSelectControl(jsonData[i]["dal.function.operation.names"], i);
btn = "<td>" + "<button id='btnRunFunc"+ i + "' class='btn btn-success btn-lg'>Run</button>" + "</td></tr>";
$("#mytable").append(tr + td2 + td3 + td4 + dt2 + btn );
}
createGoBackButton();
createInputTextParameters();
}
function loadInformationFunctionsGrid() {
$("#UserGuide").addClass("alert alert-info");
$("#UserGuide").html("<h3>Getting device functions:</h3><br/>"
+ "This API is used to retrieve the list of the available functions supported by the device. For"
+ "example a Smart Plug has two functions: one to retrieve the energy consumption and another"
+ "'boolean' function useful to change the status of the smart plug (ON/OFF). Every function"
+ "indicates the id, which can be used to access directly the function and the list of the operation"
+ "that can be invoked on the function.<br/>"
+ "P.S. If he want use a function that want some parameters he must write these into the dedicated textbox. If the API needs more parameters separate these using comma. <br/>"
+ "Example of parametes: <br/> <code>'type':'java.math.BigDecimal'</code><br/> <code>'value':1</code> <br/> etc...");
}
function createGoBackButton() {
var btn = '<button id="btnGoBack" class="btn btn-warning btn-lg">Go Back</button>';
$("#goBack").append(btn);
}
function createInputTextParameters() {
var lbl ="<label>Paramters</label>";
var txt ='<input type="text" class="form-control" name="email">';
$("#inputDiv").addClass("form-group");
$("#inputDiv").append(lbl);
$("#inputDiv").append(txt);
}
function fillSelectControl(obj, id) {
var dataList = "<td><select id='slt"+ id +"'>";
for(var j = 0; j < obj.length; j++)
dataList = dataList + "<option value='" + obj[j] + "'>" + obj[j] + "</option>";
return dataList = dataList + "</select></td>";
}
var json = "";
var goBack = "";
var deviceUID;
function jsonGETRequest(url, dataExample){
$.getJSON(apiUrl, function(data) {
alert(JSON.stringify(data));
this.json = data;
})
.done(function() {
$("#information").addClass("alert alert-success");
$("#information").text("getJSON request succeeded!");
if(goBack == "") {
loadDataIntoDeviceGrid(jsonExampleData);
loadInformationDeviceGrid();
} else if (goBack=="firstAPIRequest") {
loadDataIntoFunctionsGrid(jsonExampleDataFunctions);
loadInformationDeviceGrid();
}
})
.fail(function(jqXHR, textStatus, errorThrown) {
//alert('getJSON request failed! ' + textStatus);
$("#information").addClass("alert alert-danger");
$("#information").text("Impossible get data from API, it will be use example data" + errorThrown);
if(goBack == "") {
loadDataIntoDeviceGrid(jsonExampleData);
loadInformationDeviceGrid();
} else if (goBack=="firstAPIRequest") {
loadDataIntoFunctionsGrid(jsonExampleDataFunctions);
loadInformationFunctionsGrid();
} else if(goBack=="secondAPIRequest") {
}
})
.always(function() { });
}
function jsonPOST(url, method, paramters, dataExample) {
}
var jsonExampleData = [
{
"dal.device.status": 2,
"dal.device.UID": "ZigBee:test123",
"dal.device.driver": "ZigBee",
"service.id": 28,
"objectClass": [
"org.osgi.service.dal.Device"
]
},
{
"dal.device.status": 2,
"dal.device.UID": "ZigBee:test456",
"dal.device.driver": "ZigBee",
"service.id": 29,
"objectClass": [
"org.osgi.service.dal.Device"
]
},
{
"dal.device.status": 2,
"dal.device.UID": "ZigBee:test789",
"dal.device.driver": "ZigBee",
"service.id": 30,
"objectClass": [
"org.osgi.service.dal.Device"
]
}
];
var jsonExampleDataFunctions = [
{
"CLASS": "ismb.pert.jemma.dummydevice.DummyFunction",
"dal.function.device.UID": "ZigBee:test123",
"service.id": 27,
"dal.function.UID": "ZigBee:test123:testButton",
"objectClass": [
"org.osgi.service.dal.Function"
],
"dal.function.operation.names": [
"getData",
"reverse",
"setFalse",
"setTrue"
]
},
{
"CLASS": "ismb.pert.jemma.dummydevice.DummyFunction",
"dal.function.device.UID": "ZigBee:test456",
"service.id": 26,
"dal.function.UID": "ZigBee:test456:testButton",
"objectClass": [
"org.osgi.service.dal.Function"
],
"dal.function.operation.names": [
"getData",
"reverse",
"setFalse",
"setTrue"
]
},
{
"CLASS": "ismb.pert.jemma.dummydevice.DummyFunction",
"dal.function.device.UID": "ZigBee:test789",
"service.id": 25,
"dal.function.UID": "ZigBee:test789:testButton",
"objectClass": [
"org.osgi.service.dal.Function"
],
"dal.function.operation.names": [
"getData",
"reverse",
"setFalse",
"setTrue"
]
}
];
</script>
</body>
</html>
.is() returns a true/false value, it does not continue the jQuery chain, therefor there is no .text() function to call
As DevishOne points out in the comments to get the selected option's text do:
=$("#slt" + (parseInt(buttonElementId + 1))).children("option:selected").text();
Split that in to multiple steps and check for the particular result:
button = $("#slt" + (parseInt(buttonElementId + 1)));
if ( button )
{
childs = button.children("option");
if ( childs .....
Whenever there's no option selected, you are unable to catch that since you refer directly to a method .text() of null.

How to expand new table data rows onscreen?

Question : I have a table displaying information for university courses. There is a column on the left with a + sign next to each row. When this is pressed, I need to display data about all the students on the course (I have this data ready and waiting). However, how do I reveal this new row of data on the screen? And how would I collapse it again?
Code :
$(document).ready(function(){
$.ajax({
url: 'http://xx.xxx.xxx.xx/getCourses.php',
dataType: 'jsonp',
jsonpCallback: "courses",
success: function( data ) {
courseData = data;
drawTable(data);
}
});
$("#dataTable").on('click', '.data-button',function(){
/* text change method */
$(this).text(function( _ , currText){
return currText === '+' ? '-' : '+';
});
/* class change */
$(this).toggleClass('active');
/* get data */
var id= $(this).data('id');
//Now reveal rows of students under this course.
var studentData = courseData.courses[id];
//HOW DO I EXPAND THE EXTRA DATA ROWS ONTO THE TABLE??
})
});
function drawTable(data) {
for (var i = 0; i < data.courses.length; i++) {
drawRow(data.courses[i]);
}
}
function drawRow(rowData) {
var button='<anyElement data-id="'+ rowData.id +'" class="data-button">+</anyElement>';
var row = $("<tr />")
row.append('<td>'+button+'</td>');/* no need to wrap html in "$()" */
/* append other cells*/
row.append($("<td>" + rowData.id + "</td>"));
row.append($("<td>" + rowData.start + "</td>"));
row.append($("<td>" + rowData.end + "</td>"));
row.append($("<td>" + rowData.lecturer + "</td>"));
/* do append to DOM after row created , makes for less DOM insertions*/
$("#dataTable").append(row);
}
</script>
</head>
<body>
<table id="dataTable">
<tr>
<th>Course</th>
<th>Start</th>
<th>End</th>
<th>Lecturer</th>
</tr>
</table>
</body>
</html>
Example of The Desired Result :
Your question doesn't go into enough detail in terms of how the student data is structured but nonetheless, I've tried to come up with something, just to show how a show/hide toggle would work. Here is a JSBin: http://jsbin.com/wekepori/1/edit?html,js,output
Edit: I've updated my answer as new information on how the student data will be structured was provided in the question. Note, in my example the data is just a hardcoded dictionary as I don't have a server back-end to work with that contains your data. So, the actual network call to retrieve the student will have to be added instead of my hardcode.
HTML:
<table id="dataTable" border="1">
<tr>
<th>Id</th>
<th>Course</th>
<th>Start</th>
<th>End</th>
<th>Lecturer</th>
</tr>
</table>
JavaScript:
$(document).ready(function(){
// $.ajax({
// url: 'http://xx.xxx.xxx.xx/getCourses.php',
// dataType: 'jsonp',
// jsonpCallback: "courses",
// success: function( data ) {
// courseData = data;
// drawTable(data);
// }
// });
var data = {
courses: [{
id: 1,
start: 0,
end: 0,
lecturer: "Mr. Smith"
},
{
id: 2,
start: 0,
end: 0,
lecturer: "Mr. Boon"
}]
};
var courseData = data;
drawTable(data);
$("#dataTable").on('click', '.data-button',function(){
var showStudentRow = $(this).text() === '+' ? true : false;
/* text change method */
$(this).text(function( _ , currText){
return currText === '+' ? '-' : '+';
});
/* class change */
$(this).toggleClass('active');
/* get data */
var id= $(this).data('id');
//Now reveal rows of students under this course.
//var studentData = courseData.courses[id];
//HOW DO I EXPAND THE EXTRA DATA ROWS ONTO THE TABLE?? see below v v
var studentData = [{
id: 23,
name: "Joe Bloggs"
},
{
id: 34,
name: "Marry Brown"
},
{
id: 55,
name: "Alan James"
}
];
if (showStudentRow) {
var trCourseRow = $(this).parent().parent();
var newStudentRow = addHeaderStudentRow(id, trCourseRow);
newStudentRow = addStudentRow(id, newStudentRow, studentData[0]);
newStudentRow = addStudentRow(id, newStudentRow, studentData[1]);
newStudentRow = addStudentRow(id, newStudentRow, studentData[2]);
}
else {
removeStudentRow(id);
}
});
});
function drawTable(data) {
for (var i = 0; i < data.courses.length; i++) {
drawRow(data.courses[i]);
}
}
function addHeaderStudentRow(courseRowId, courseRow) {
var row = $('<tr></tr>')
.css('font-weight', 'bold')
.addClass('student' + courseRowId)
.append('<td>Student Id</td><td colspan="4">Name</td>');
row.insertAfter(courseRow);
return row;
}
function removeStudentRow(courseRowId) {
$('.student' + courseRowId).remove();
}
function addStudentRow(courseRowId, courseRow, studentRowData) {
var row = $('<tr></tr>')
.css('font-weight', 'bold')
.addClass('student' + courseRowId);
row.append($('<td>' + studentRowData.id + '</td>'));
row.append($('<td colspan="4">' + studentRowData.name + '</td>'));
row.insertAfter(courseRow);
return row;
}
function drawRow(rowData) {
var button='<div data-id="'+ rowData.id +'" class="data-button">+</div>';
var row = $("<tr />");
row.append('<td>'+button+'</td>');/* no need to wrap html in "$()" */
/* append other cells*/
row.append($("<td>" + rowData.id + "</td>"));
row.append($("<td>" + rowData.start + "</td>"));
row.append($("<td>" + rowData.end + "</td>"));
row.append($("<td>" + rowData.lecturer + "</td>"));
/* do append to DOM after row created , makes for less DOM insertions*/
$("#dataTable").append(row);
}

Categories