Thymeleaf table row click not recognizing js function - spring

The onclick event is complaining that the java script function is not defined.
<body>
<div layout:fragment="content" th:remove="tag">
<div class="container">
<h6 class="mb-3">Restaurant Order Details</h6>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th scope="col">Order Id</th>
<th scope="col">Order Details</th>
<th scope="col">Date</th>
<th scope="col">Amount</th>
</tr>
</thead>
<tbody>
<tr th:each="order : ${orders}" style="cursor: pointer"
th:attr="onclick=|getOrderItems('${order.orderId}')|">
<td scope="row" th:text="${order.orderId}"></td>
<td th:text="${order.orderDetais}"></td>
<td th:text="${order.orderDate}"></td>
<td th:text="${order.amount}"></td>
</tr>
<tr>
<td colspan="3">Total</td>
<td th:text="${grandTotal}"></td>
</tr>
</tbody>
</table>
<div class="mb-4"></div>
</div>
</div>
<script>
function getOrderItems(orderId) {
alert("order details here");
}
</script>
</body>
When I click on the table row I get
Uncaught ReferenceError: getOrderItems is not defined
at HTMLTableRowElement.onclick
When I replace getOrderItems with a simple alert instead, the alert is fired. How do I fix this?

I know this is probably not the answer you looking for, it's just a suggestion:
In JavaScript, you can actually use the thymeleaf variables like this:
var myVar = [[${order.orderId}]];

The issue here was I declared my <script> outside the <div layout:fragment="content" th:remove="tag"> tag. Since this is a fragment, thymeleaf only rendered everything within this scope. Putting the script tag inside this solved the issue.

You are not passing thymeleaf variable to javascript. You can issue <script> outside your (just above </body>) and still pass variable to JS.
<script th:inline="javascript">
/*<![CDATA[*/
var orders = [[${orders}]];
function getOrderItems(orders) {
alert("order details here ");
}
/*]]>*/
</script>
Then you can call JS method on your html onclick event.
<tr th:each="order : ${orders}" style="cursor: pointer"
th:attr="onclick=|getOrderItems(orders)}')|">
<td scope="row" th:text="${order.orderId}"></td>
<td th:text="${order.orderDetais}"></td>
<td th:text="${order.orderDate}"></td>
<td th:text="${order.amount}"></td>
</tr>
However, I still see a challenge if you wish to pass every single order to javascript. I haven't used <script> inside the th:each loop.

Related

Bootstrap Modal window and Thymeleaf

I have a project with Spring Mvc and I want to use Bootstrap modal windows and Thymeleaf. I hava a view students.jsp witch get list of students from model when I make loop without Thymeleaf everything work ok.
I use JS. But when I use Thymeleaf model windows didn't work ok.
<table class="table table-hover">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody>
<tr id="user-${user.id}" th:each="user: ${students}">
<td th:text="${user.id}" />
<td th:text="${user.firstName}" />
<td th:text="${user.lastName}" />
<td>
<button type="button" class="btn btn-primary editButton"
data-toggle="modal" data-target="#myModal" data-user-id="${user.id}">Edit</button>
</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
$("#myModal").on('show.bs.modal', function(e) {
var userId = $(e.relatedTarget).data('user-id');
var cols = $('#user-' + userId + ' td');
var firstName = $(cols[0]).text();
var lastName = $(cols[1]).text();
var email = $(cols[2]).text();
$('#firstNameInput').val(firstName);
$('#lastNameInput').val(lastName);
$('#emailInput').val(email);
});
$("#myModal").on('hidden.bs.modal', function() {
var form = $(this).find('form');
form[0].reset();
});
</script>
It doesn't get data from list. I don't know how to solve this problem. Please help me :)
There's a small problem with data-user-id attribute in your "Edit" button.
Instead of:
data-user-id="${user.id}"
...you should have:
th:data-user-id="${user.id}"
...so that the attribute is processed by Thymeleaf and ${user.id} actually replaced with expected value.
<tr th:each="user: ${students}" th:id="'user-' + ${user.id}">
<td th:text="${user.id}" />
<td th:text="${user.firstName}" />
<td th:text="${user.lastName}" />
<td th:text="${user.email}" />
<td>
<button type="button" class="btn btn-primary editButton"
data-toggle="modal" data-target="#myModal"
th:data-user-id="${user.id}">Edit</button>
</td>
</tr>

How to show checkbox selected values in the same laravel view before submitting the form?

I have create.blade.php view. And that view showing a table with checkbox in each row. Now I want to show the checked row on the same view next to this table. Till now what I am getting the all the checked values but how can show it the same view before sending any post request to the server.
Here is some code-
#if(count($movies) > 0)
<div class="table-responsive">
<table class="table table-striped table-hover" data-toggle="dataTable"
data-form="deleteForm">
<thead>
<tr>
<th></th>
<th scope="col">Name</th>
</tr>
</thead>
<tbody>
<label>Select movies</label>
#foreach($movies as $movie)
<tr>
<td>
<input class="form-check" type="checkbox" name="movie_cb" id=" .
{{$movie->id}}" value="{{$movie->name}}">
</td>
<td>{{$infeedVideo->name}}</td>
</tr>
#endforeach
</tbody>
</table>
#else
<div class="text-center">
<hr>
<p class="text-center">No movies found</p>
</div>
#endif
app.blade.php
<script type="text/javascript">
$(document).ready(function() {
$("#showCBs").click(function(){
var favorite = [];
$.each($("input[name='movie_cb']:checked"), function(){
favorite.push($(this).val());
});
alert("My favourite movies are: " + favorite.join(", "));
});
});
</script>
Now how can I pass the favorite array from app.blade.php to my laravel view create.blade.php. Thank you

Kendo grid format decimal

I've created a kendo grid based on a html table. I want the number in the grid to display only 2 decimals, but I can not figure out how to do this. Please help. See my code below.
<table id='test'>
<tr>
<th data-field='field1' data-type='number' data-template='#= kendo.toString(field1, "n2") #'>
ColumnHeader
</th>
</tr>
<tr>
<td>2.2579</td>
</tr>
</table>
<script>
$(document).ready(function(){
$("#plStatsGrid").kendoGrid({});
});
</script>
This is a basic scripting error. Your script is looking for table with id plStatsGrid, but your table has id test. Working fiddle.
<table id='plStatsGrid'>
<tr>
<th data-field='field1' data-type='number' data-template='#= kendo.toString(field1, "n2") #'>
ColumnHeader
</th>
</tr>
<tr>
<td>2.2579</td>
</tr>
</table>
<script>
$(document).ready(function(){
$("#plStatsGrid").kendoGrid({});
});
</script>

Selenium webdriver using TestNG - Cannot locate correct Xpath of input field from label

here i want to fill the input field, but unable to access it by Xpath... Plz Help me out..
and the Code is below....
<table class="detailList" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="labelCol">
<div id="div1">
<div class="pbSubsection">
<table class="detailList" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="data2Col" colspan="2">
<span style="font-Size:12px;">
Process Name
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</td>
<td style="text-align:left;" class="data2Col">
<div id=div2">
<div class="pbSubsection">
<table class="detailList" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="data2Col" colspan="2">
<div id="div3" class="requiredInput">
<div id="div4" class="requiredBlock"></div>
<input name="pName" style="width:50%;" type="text">
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</td>
</tr>
</tbody>
</table>
iam trying
WebElement ele = driver.findElement(By.xpath("//span[text()='Process Name']/preceding::td/div/input[#type='text']"));
ele.sendKeys("PM 001");
But here after preceding i know its wrong.. Plz Help me out with this.......
Here the name attribute value of input and div id's will change dynamically...
so iam trying to find by the label and preceding input tag...
Thanks in Advance
Your XPath is entirely wrong.
//span[normalize-space(text())='Process Name']/ancestor::tr/descendant::input
Is what you are after.
If the name of that input doesn't change, you can simply get it via:
driver.findElement(By.name("pName"));
Your XPath falls over at the first hurdle simply because that span has a lot of whitespacing around "Process Name", so use normalize-space to force it to strip the whitespaces from the text before comparing it.
You are also then falling over at the next stop, preceding ...you are the the span's level here, it's as deep as you can go, there's nothing 'preceding' it in the first place.
//span[normalize-space()='Process Name']//ancestor::tr//div//input[#type='text']

ng-repeat and the mouseover event

this seems like a scope problem, but i am not sure. my goal is to highlight a single row in a table. that implies that any previously highlighted row is returned to an unhighlighted state. the rows are created with the ng-repeat directive, like this:
<div id="myFedContents" style="height:320px" ng-controller="Controller2" class="scroller">
<table border="0" class="span12 table table-condensed" style="margin-left:0px" id="tblData">
<thead>
<tr><th>Year</th><th>Name</th><th>Useful Flag</th></tr>
</thead>
<tbody id="allRows">
<tr ng-repeat="item in itemlist | filter:thisText" ng-style="myStyle"> <td class="span1" valign="top"><a tabindex="-1" href="#">{{item.year}}</a></td>
<td id="{{item.id}}"> <a tabindex="-1" href="#" ng-click="myStyle={'background-color':'#cccccc'};">{{item.name}}</a>
</td> <td>
{{item.usefulflag}
</td> </tr>
</tbody>
</table>
</div>
i have code in a .js file that looks like this:
$("tr").mouseenter(function(){
alert("mouseenter");
});
the row in the table header reacts with the alert, but there is no reaction from the rows created by ng-repeat. how do i correct?
You can actually achieve this effect by using an ng-class in conjuction with ng-mouseenter and ng-mouseleave like so:
<div id="myFedContents" style="height:320px" ng-controller="Controller2" class="scroller">
<table border="0" class="span12 table table-condensed" style="margin-left:0px" id="tblData">
<thead>
<tr>
<th>Year</th>
<th>Name</th>
<th>Useful Flag</th>
</tr>
</thead>
<tbody id="allRows">
<tr ng-repeat="item in itemlist | filter:thisText" ng-style="myStyle" ng-class="highlightclass" ng-mouseenter="highlightclass='highlight'" ng-mouseleave="highlightclass=''">
<td class="span1" valign="top"><a tabindex="-1" href="#">{{item.year}}</a>
</td>
<td id="{{item.id}}"> <a tabindex="-1" href="#" ng-click="myStyle={'background-color':'#cccccc'};">{{item.name}}</a>
</td>
<td>
{{item.usefulflag}
</td>
</tr>
</tbody>
</table>
</div>
In this case you don't need the jquery syntax. If you haven't already you should also read https://stackoverflow.com/a/15012542/281335.

Resources