Datatables: delete row on the client side - html

I have a SpringBoot application that uses datatables ,
here my datatable on the template
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Position</th>
<th>Actions1</th>
<th>Actions2</th>
</tr>
</thead>
<tbody>
<tbody>
<tr th:each="pic: ${pics}" >
<td class="col_name" >
<div class="box small">
<img th:src="${pic}"/>
</div>
</td>
<td class="col_actions">
<a style="color:#808080; margin-right: 10px;">
<input type="radio" name="${pic}" th:field="*{nadal}" th:value="${pic}" >Nadal<br>
</a>
</td>
<td><button>Delete</button></td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Position</th>
<th>Actions1</th>
<th>Actions2</th>
</tr>
</tfoot>
</table>
and the javascript code on the same page:
<script type="text/javascript">
$(document).ready(function() {
$('#example').DataTable({
searching: false,
paging: false
}).on("click", "button", function(){
alert('deleting row');
console.log($(this).parent());
table.row($(this).parents('tr')).remove().draw(false);
});
});
</script>
but When I click it makes a server submit of the form

try this:
<script type="text/javascript">
$(document).ready(function() {
const table = $('#example').DataTable({
searching: false,
paging: false
}).on("click", "button", function () {
alert('deleting row');
console.log($(this).parent());
table.row($(this).parents('tr')).remove().draw(false);
});
});
</script>

The easiest way to do whatever you want regardless of the scenario in all programming languages is just create a variable and an if statement. create a Boolean variable in the start and set the value to false. Whenever you want to display something or not display it, just create an if statement saying
if(<name of variable>){
display()
}else{
dontDisplay()
}
You don't have to say === true, you just need to give the variable's name since if you give the name it defaults to true, you only need to say === false for an else if statement.
This works all the time and you can also eliminate false positives, negatives or double alerts in many cases.

Related

Footable and Validation error message in Mobile view MVC

In my MVC 5 Web App I use footable. In a table I have fields radio buttons for example that are built the form.
here is the code:
<thead>
<tr>
<th></th>
#foreach (var labelfreqdep in ViewBag.rbFreqDep)
{
<th style="text-align:center;" data-breakpoints="xs sm">
<label for="FrequencyID">#labelfreqdep.FrequencyDescription</label>
</th>
}
<th data-breakpoints="xs sm"></th>
</tr>
</thead>
<tbody>
<tr>
<td>First Chooses</td>
#foreach (var freqdep in ViewBag.rbFreqDep)
{
<td class="rd">
<input type="radio" name="A3_1" id="A3_1" value="#freqdep.FrequencyDescription" data-val="true" data-val-required="Please select">
</td>
}
<td class="rd">#Html.ValidationMessageFor(model => model.A3_1, "", new { #class = "text-danger" })</td>
</tr>
</tbody>
</table>
I also use validation for empty fields with data-val="true". The problem is that doesn't display the "Please select" message in mobile view. It works ok for desktop view. When I have expanded the tr with the plus icon the message appears. Can we just expand the rows on submit so the message to be displayed?
Any idea?
Edited
I used
$("#survey_form").submit(function (event) {
$('.surveytable').footable({
"expandAll": true
});
});`
It expands the rows on submit but it doesn't show the validation errors
For anyone who has the same issue, I solved it by giving an id to the button and then handle it through jquery
<script type="text/javascript">
jQuery(function($){
$('.surveytable').footable()
$("#survey_btn").click(function (event) {
$('.surveytable').footable({
"expandAll": true
});
});
});
</script>

How to switch between different view by changing the content in <div> tag

I have different view (grid and list). I am using datatable as list view but the datatable function is not working. I am using ajax to refresh the content in div tag.
$('#grid').click(function(){
$('#searchBar').show();
$.ajax({
type:'GET',
url:'/refreshList',
dataType: 'HTML',
success:function(html){
$('#body').html(html);
},
error:function(){
}
});
});
In my another list view file
<table class="table display nowrap" cellspacing="0" width="100%" id="main-table">
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
<td></td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function(){
$('#main-table').DataTable({
"responsive": true
});
});
</script>
I will refresh the content of div replace by this table, but it shows without datatable function. ps.written in 2 different file.

Why won't "draggable = 'true'" work on React rendered component?

this is driving me mad and hope someone might be able to help.
I have this React.Component:
var Vehicle = React.createClass({
ondragend: function(e) {
e.preventDefault();
// Logic here
console.log('onDragOver');
},
ondragstart: function(e){
e.preventDefault();
console.log('ondragstart');
},
render: function() {
that = this
var loads = this.props.truck.map(function(load , i){
load.truckid = i
return (
<tr key={i} draggable="true" dragstart={that.ondragstart} dragend={that.ondragend}>
<td>
{load.load_number}
</td>
<td>
{load.stops[0].location_name}
</td>
<td>
{load.stops[1].location_name}
</td>
</tr>
)
})
return (
<div className="panel panel-primary" draggable="true">
<VehiclePanelHeading vehicleNbr={this.props.vehicleNbr}></VehiclePanelHeading>
<div className="panel-body" >
<table className="table">
<tbody>
{loads}
</tbody>
</table>
</div>
</div>
)
}
});
As you can see, I am trying to make the s draggable. Unfortunetly, this won't work, even if I use the Chrome dev tools to manually add this into the html in the browser.
I have tried removing my link to Bootstrap incase this is something to do with the CSS rules, and also tried to render just a html table with no dynamic values.
I can't see how the code in this fiddle:
jsFiddle
Works by setting the draggable=true in the render function, but mine won't.
Thanks in advance for any help.
Edit
Added the dropEnd/Start handlers but no change.
Curiously, if I add draggable=true to the div.panel container, this is draggable whilst the containing s remain not.
Update
If I create a quick .html page with this table:
<table className="table">
<thead>
<tr>
<td>Name</td>
<td>Tangyness</td>
</tr>
</thead>
<tbody>
<tr draggable="true">
<td>Apple</td>
<td>4</td>
</tr>
<tr draggable="true">
<td>Orange</td>
<td>7</td>
</tr>
</tbody>
</table>
Then the desired draggble = true works on the table rows. However, if I paste this into the React render function:
return (
<div className="panel panel-primary" >
<VehiclePanelHeading vehicleNbr={this.props.vehicleNbr}></VehiclePanelHeading>
<div className="panel-body" >
<table className="table">
<thead>
<tr>
<td>Name</td>
<td>Tangyness</td>
</tr>
</thead>
<tbody>
<tr draggable="true">
<td>Apple</td>
<td>4</td>
</tr>
<tr draggable="true">
<td>Orange</td>
<td>7</td>
</tr>
</tbody>
</table>
</div>
</div>
)
Then suddenly, the 'draggability' is lost.
It should work, but you probably want to implement onDragOver event(s) too. Otherwise it will look like it doesn't work because you can drag your component, but don't have any legal place to drop it. onDragOver lets you specify if an element accepts dropping and which elements it accepts.
As you can see in the fiddle you linked there are onDragOver events which look something like this
onDragOver: function(e) {
e.preventDefault();
// Logic here
}
Calling e.preventDefault(); tells the browser that dropping is possible here. You can put the onDragOver event on any of your parent elements, or on the tr itself. You can read more about drop targets here. If you remove the onDragOver event from the jsFiddle you linked the code in the fiddle stops functioning too.
If you implement onDragOver you will be able to implement an onDrop event on your table that handles dropped tr elements.
Here is your code with the events implemented:
var Vehicle = React.createClass({
onDragOver: function(e) {
e.preventDefault();
// Logic here
console.log('onDragOver');
},
onDragStart: function(e){
e.dataTransfer.setData('id', 'setTheId');
console.log('onDragStart');
},
onDrop: function(e) {
console.log('onDrop');
var id = event.dataTransfer.getData('id');
console.log('Dropped with id:', id);
},
render: function() {
that = this;
var loads = this.props.truck.map(function(load , i){
load.truckid = i
return (
<tr key={i} draggable="true" onDragOver={that.onDragOver} onDragStart={that.onDragStart}>
<td>
{load.load_number}
</td>
<td>
{load.stops[0].location_name}
</td>
<td>
{load.stops[1].location_name}
</td>
</tr>
)
})
return (
<div>
<div className="panel-body" >
<table className="table" onDrop={this.onDrop}>
<tbody>
{loads}
</tbody>
</table>
</div>
</div>
)
}
});
Here is a jsFiddle of this: http://jsfiddle.net/kb3gN/10761/
The reason that the item doesn't seem to drag is you have e.preventDefault(); inside onDragStart function, which prevents it from showing the default dragging movement. Just remove that line, so it would look like this and it should work:
var Vehicle = React.createClass({
...
onDragStart: function(e){
// REMOVED THIS LINE
//e.preventDefault();
console.log('ondragstart');
},
...

AngularJS Hide rows from table on given condition when a button is clicked

I'm trying to hide some rows from a table when a button is clicked. I want to hide just the rows where the number of exams is equals to zero.
HTML code:
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide();"> HIDE ROWS</button>
<br/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-class="{'showNot' : item.examsNum === 0}" ng-repeat="item in data.records">
<td>{{item.name}}</td>
<td>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
</div>
AngularJS:
var myApp = angular.module('myApp', []);
myApp.controller('myController', ['$scope', function ($scope) {
$scope.data = {
records: [{
name: 'Mel',
examsNum: 2
}, {
name: 'Sarah',
examsNum: 2
}, {
name: 'Jane',
examsNum: 0
}]
};
$scope.hide = function () {
angular.element('.showNot').css("display", "none");
};
}]);
Here is the jsfiddle: link
I'm pretty new to AngularJS, and I can't see what I'm doing wrong.
Thanks!
Try using a show/hide flag, and use it in ng-show along with the zero check:
Here's a fiddle.
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide();"> HIDE ROWS</button>
<br/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-hide="(item.examsNum == 0) && hideZero" ng-repeat="item in data.records">
<td>{{item.name}}</td>
<td>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
and
myApp.controller('myController', ['$scope', function ($scope) {
$scope.data = {
records: [{
name: 'Mel',
examsNum: 2
}, {
name: 'Sarah',
examsNum: 2
}, {
name: 'Jane',
examsNum: 0
}]
};
$scope.hide = function () {
$scope.hideZero = !$scope.hideZero;
};
}]);
You can give an id to your table <table id="table"> then change your selector to
var elem = document.querySelector('#table');
angular.element(elem.querySelector('.showNot')).css('display', 'none')
We cant use class selectors easily in jQlite - Limited to lookups by tag name but this should work your you
JSFiddle Link
you need to use the ng-show or ng-hide directive insted of display none
html
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide()"> HIDE ROWS</button>
<br/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-show="Display" ng-repeat="item in data.records">
<td>{{item.name}}</td>
<td>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
</div>
script
var myApp = angular.module('myApp', []);
myApp.controller('myController', ['$scope', function ($scope) {
$scope.data = {
records: [{
name: 'Mel',
examsNum: 2
}, {
name: 'Sarah',
examsNum: 2
}, {
name: 'Jane',
examsNum: 0
}]
};
$scope.Display = true;
$scope.hide = function () {
$scope.Display = !$scope.Display ;
};
}]);
Perhaps using a filter is more correct.
https://docs.angularjs.org/api/ng/service/$filter
Filters may be used to hide items in a list based on some criteria - which sounds like what you are doing
Okay. So you got something wrong over here. the 'item' is only available inside the scope of ng-repeat. You cannot access it at the same level as ng-repeat.
Here is a working version of your code. And please use ng-hide/ng-show for such things. Its more efficient.
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide();"> HIDE ROWS</button>
<br />
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data.records">
<td ng-hide='item.examsNum === 0'>{{item.name}}</td>
<td ng-hide='item.examsNum === 0'>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
</div>

Retrieving values from a table cell <td> to a controller

I'm trying to get a specific value from a table cell and pass is to a controller. But it doesn't seem to be working. I show you some of my codes:
This is in the controller:
def searchUser = {
String abc = request.getParameter("harrow")
println(abc)
}
This is in the html page:
<form>
<div style="height: 250px; overflow: scroll; width: 100%;">
<table id="normal">
<g:each in = "${result}">
<tr id="btn">
<td width=10% >${it.ID}</td>
<td width=25% id="harrow">${it.username}</td>
</tr>
</g:each>
</table>
</div>
<input type ="submit" name ="abc" id="opener">
</form>
EDIT
AJAX:
$("#edittable").on('click', function() {
$.ajax({
url: URL,
data: $(this).serialize(),
type: "POST",
success: function(html){
//do something with the `html` returned from the server here
$("#edit1").html(html).dialog("open")
},
error: function(jqXHR, textStatus, errorThrown){
alert('error: ' + textStatus + ': ' + errorThrown);
}
});
return false;//suppress natural form selection
});
I can get the value to pass to the controller, but right now it only retrieves the first row of values rather than the other. Is there something wrong with my AJAX codes? Thank you guys so much.
So to show details of the row, one of the approaches can be:
CONTROLLER METHODS
def rows = [
[id:1, name:'name1'],
[id:2, name:'name2'],
[id:3, name:'name3']
]
def show(){
[results:rows]
}
def showLine(Long id){
render rows.find {it.id == id }
}
VIEW
<html>
<head>
<g:javascript library="jquery" />
<r:layoutResources />
</head>
<body>
<table>
<thead>
<tr>
<th>Action</th>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<g:each in="${results}" status="i" var="r">
<tr>
<td><g:remoteLink value="Details" id="${r.id}" action="showLine" update="lineDetails">Details</g:remoteLink></td>
<td>${r.id}</td>
<td>${r.name}</td>
</tr>
</g:each>
</tbody>
</table>
<div id="lineDetails">
</div>
</body>
</html>
Basically you call showLine method using AJAX and passing row object id. Then you search for the object and render it back. Rendered data is put into div under the table. It's up to you if you use onclick, button or link in the table. It's also up to you how to show details on results page - use jquery dialog, or something else. Hope it helps