I want to get a data from listing and retrieve to popup.. when I use getElementById, it will only get a single id from another input. not from listing that i want.. so, I've come an idea to use array.. but I don't know how.. I'm using Java Play Framework
here is my code..
display.html
<script>
function openModifySchedule(staffId) {
if (!checkRequiredField()) {
alert("There Is Error(s) In The Form. Please Fix It Before Proceed.");
return;
}
var staffId = document.getElementById("staffId").value;
if (staffId == "") {
alert("Please Select Doctor Before Proceed");
return;
}
var url = "/DoctorSchedules/modifySchedulePopup?staffId=" + staffId;
mywindow = window.open(url,"mywindow","location=no,resizable=1,width=700,height=650,menubar=no,center=yes");
mywindow.moveTo(420,100);
}
</script>
<input type="hidden" id="staffId" name="staffDetails.staffId" value="${staffDetails?.staffId}">
<tbody>
#{list items:staffScheduleList , as:'stffSchedule'}
<tr id="list" align="center">
<td></td>
<td id="scheduleDate">${stffSchedule.scheduleDate}</td>
<td id="staffId"><a onClick="openModifySchedule()" href="#">${stffSchedule.staffId}</a></td>
<td id="staffName">${stffSchedule.staffName}</td>
<td id="deptName">${stffSchedule.deptName}</td>
<td></td>
<td></td>
<td></td>
<td id="contactNo">${stffSchedule.contactNo}</td>
</tr>
#{/list}
</tbody>
here is the function in controller..
display.java
public static void modifySchedulePopup(String staffId){
StaffDetails staffDetails = StaffDetails.find("byStaffId", staffId).first();
StaffSchedule staffSchedules = StaffSchedule.find("byStaffId", staffId).first();
renderTemplate("DoctorSchedules/doctorScheduleModifyPopup.html", staffDetails,staffSchedules);
}
hope someone can explain.
In the DOM, no two elements may have the same id attribute. Since all of the "td" elements in your table have id="staffId", getElementById() is free to return any one of them.
Since Play! comes with JQuery, you might was well use that instead of straight JavaScript (it's much easier). Briefly, you attach the same "click" event handler to all of the links and the click event handler knows which element was being clicked.
Here's simple snippet that demonstrates this:
<script>
$(function() {
$(".staff-id").click(function() { // attach the click event handler
var staffId = $(this).text();
alert(staffId); // open your new window here
});
});
</script>
#{list items:staffScheduleList, as:'stffSchedule'}
<tr id="list" align="center">
<td></td>
<td>${stffSchedule.scheduleDate}</td>
<td><a class="staff-id" href="#">${stffSchedule.staffId}</a></td>
<td>${stffSchedule.staffName}</td>
<td>${stffSchedule.deptName}</td>
<td></td>
<td></td>
<td></td>
<td id="contactNo">${stffSchedule.contactNo}</td>
</tr>
#{/list}
Related
I'm actually trying to create a listener with a click function in javascript to create redirections inside a table.
document.body.addEventListener('click', evt => {
const link = evt.target.closest('td.loader');
if (!link) return;
evt.preventDefault();
window.location.href = link.href;
});
<table>
<tr>
<td class="loader" data-href="http://www.google.com">
Google
</td>
</tr>
</table>
Don't understand what is missing...help please!
A couple of syntax errors in yours, try this:
let tableLink = document.querySelector('td.loader');
tableLink.addEventListener('click', evt => {
const link = tableLink.getAttribute('data-href');
evt.preventDefault();
window.location.href = link;
});
<table>
<tr>
<td class="loader" data-href="http://www.google.com">
Google
</td>
</tr>
</table>
If there are more than one you can leverage a loop and hit it via an element parameter:
let tableLinks = document.querySelectorAll('td.loader');
tableLinks.forEach((el) => {
el.addEventListener('click', evt => {
const link = el.getAttribute('data-href');
evt.preventDefault();
window.location.href = link;
});
})
<table>
<tr>
<td class="loader" data-href="http://www.google.com">
Google
</td>
<td class="loader" data-href="http://www.facebook.com">
Facebook
</td>
<td class="loader" data-href="http://www.youtube.com">
Youtube
</td>
</tr>
</table>
You did a slight mistake here. Links must be in anchor tag. Then only browsers can identify it as a link. So I changed your HTML as below now it's working fine.
<table>
<tr>
<td class="loader">
Google
</td>
</tr>
</table>
So, to be clear, I didn't find a 100% good solution with javascript. The best I can do is to put a div inside each cell of the table, set with height and width 100% like this:
<table>
<tr>
<td class="loader">
<a href="google.com">
<div style="height:100%;width:100%;">
</a>
Google
</td>
</tr>
</table>
Then, I can use this javascript:
document.body.addEventListener('click', evt => {
const link = evt.target.closest('td.loader a');
if (!link) return;
evt.preventDefault();
document.body.innerHTML = '<h3 style="color:red">loading link</h3>';
const href = $(this).find("a").attr("href");
window.location = href;
});
In facts, it works because I I can use the html link and also the javascript listener. But it's not perfect, due to the css (impossible to have a full cell clickable if some cells are composed with different numbers of lines).
But it's not bad!
At the end, I've realized that semantic ui (I'm using this css framework for this application) purpose a class .selectable who do all the job for me.
Perfect result and less javascript code so I've choosen this solution.
Just in case someone has the same problem, Bootstrap has the same property.
Here is my HTML code.
How can I get the value of the data attribute when click the cell?
<td id = "orderIds" data-cids="213,431">orders</td>
What should I use to trigger an event when I click on the <td> cell?
Please check below mentioned solution.
$('td').click(function(){
alert($(this).data('cids'));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td id = "orderIds" data-cids="213,431">orders</td>
<td data-cids="23,43">12</td>
<td data-cids="21,41">23</td>
<td data-cids="13,31">34</td>
</tr>
</table>
you need clicked cell data attribute so use of this will do the needful. use following snippet and it should work.
$('td').click(function(){
var data = $(this).data('cids');
})
Bind a click event handler by selecting cell using the has-attribute selector(optional) and get data attribute value using data() method.
$('td[data-cids]').click(function() {
console.log($(this).data('cids'));
// or use `this.dataset.cids`
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td data-cids="213,431">orders</td>
<td data-cids="123,234">orders</td>
</tr>
</table>
With pure js...
orderIds.onclick=function(){
console.log(this.dataset.cids)
}
you can also use $('#orderIds) with jQuery
i have a table with a few rows. i want to access the cells with the value that are in the same row as the anchor that triggers the function populateRow();
(i hope i explained it in a clear way).
any idea how to do that?
<tr>
<td>
some value
</td>
<td>
update
</td>
</tr>
<tr>
<td>
another value
</td>
<td>
update
</td>
</tr>
The populateRow() function would need to know which anchor was clicked, so you'd need to either pass this to it to give it a reference to said anchor:
onclick="populateRow(this);"
function populateRow(anchor) {
var row = $(anchor).closest("tr");
var firstCellValue = row.find("td").first().text();
}
...and from there use .closest() to navigate up the DOM to the containing tr element.
Or, better, bind the click event handler with jQuery rather than putting it inline on every row:
$(document).ready(function() {
$("#idOfYourTable").on("click", "a", function(e) {
var row = $(this).closest("tr");
var firstCellValue = row.find("td").first().text();
console.log(firstCellValue);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="idOfYourTable">
<tr>
<td>Value 1</td>
<td>
update
</td>
</tr>
<tr>
<td>Value 2</td>
<td>
update
</td>
</tr>
</table>
(Click the "Run..." button to see it working.)
I don't know what is that populateRow() function for, but if you want to get value on the first td of the same tr, then you can try testing this:
onclick="alert($(this).closest('tr').find('td:first').text())"
if you want to pass it in populateRow() function, you can:
onclick="populateRow($(this).closest('tr').find('td:first').text())"
Or ...
It would be more neat if you pass the element then process it later inside your function:
onclick="populateRow(this)"
function populateRow(elm) {
var val = $(elm).closest('tr').find('td:first').text();
alert(val);
}
Hope this helps. Good luck!
Okay, i'm completetly stuck. I tried every answer on here but I just can't get it to work.
My Aim: Updating dynamic forms with jQuery & AJAX
What's the problem: When clicking one of the "save" buttons it only saves the first value, I tried to do it with different ID's but as a newbie to jQuery I don't think I'm doing this right.
jQuery
$(document).ready(function() {
$("textarea").keyup(function(){
var txtArea = $('.txta').val();
var scriptString = $('.button').attr("url");
$(".button").click(function(){
$.ajax({
method: 'get',
url: '../wp-content/plugins/custom-text-editor/writefile.php',
data: {
'myString': scriptString,
'txt': txtArea,
'ajax': true
},
success: function(data) {
$('#'+myString).text(data);
return false;
}
});
});
});
});
writefile.php
$file = fopen("files/tab1.txt","w");
$txt = $_GET['txt'];
fwrite($file,$txt);
fclose($file);
echo "OK!";
Generated HTML
<table class=bordered>
<tr>
<th>Filename</th>
<th></th>
<th></th>
</tr>
<tr class=header>
<td class='plus'>+</td>
<td><p>tab1.txt</p></td>
<td><span id='ss' class='data'></span></td>
</tr>
<tr>
<td colspan="3" class="nopad">
<p><textarea cols="80" class="txta" rows="12" id="tab1.txt">asdasd</textarea>
<span id='tab1.txt' class='button' rel='qyz' url=tab1.txt>Save</span></p>
</td>
</tr>
<tr class=header>
<td class='plus'>+</td>
<td><p>tab2.txt</p></td>
<td><span id='ss' class='data'></span></td>
</tr>
<tr>
<td colspan="3" class="nopad">
<p><textarea cols="80" class="txta" rows="12" id="tab2.txt">This is file 2</textarea>
<span id='tab2.txt' class='button' rel='qyz' url=tab2.txt>Save</span></p>
</td>
</tr>
<tr class=header>
<td class='plus'>+</td>
<td><p>tab3.txt</p></td>
<td><span id='ss' class='data'></span></td>
</tr>
<tr>
<td colspan="3" class="nopad">
<p><textarea cols="80" class="txta" rows="12" id="tab3.txt">And File 3</textarea>
<span id='tab3.txt' class='button' rel='qyz' url=tab3.txt>Save</span></p>
</td>
</tr>
<tr class=header>
<td class='plus'>+</td>
<td><p>tab4.txt</p></td>
<td><span id='ss' class='data'></span></td>
</tr>
<tr>
<td colspan="3" class="nopad">
<p><textarea cols="80" class="txta" rows="12" id="tab4.txt">It works!</textarea>
<span id='tab4.txt' class='button' rel='qyz' url=tab4.txt>Save</span></p>
</td>
</tr>
</table>
This should resolve your problem:
$(document).ready(function () {
$(".button").click(function () {
var txtArea = $(this).closest('tr').find('.txta').val();
var scriptString = $(this).closest('tr').find('.button').attr("url");
$.ajax({
method: 'get',
url: '../wp-content/plugins/custom-text-editor/writefile.php',
data: {
'myString': scriptString,
'txt': txtArea,
'ajax': true
},
success: function (data) {
$('#' + myString).text(data);
return false;
}
});
});
});
How it works:
$(this) gives access to an element being clicked. Even "this" (without dollar sign and without quotes) gives such access, but it is not a jquery object, we need jquery object for further manipulations.
closest('tr') iterates the chain of parent elements until it finds an element satisfying the specified selector (in this case it searches for closest tr-element).
find('.txta') iterates the descendants (of the current element) until it finds an element satisfying the specified selector (in this case it searches for any element having "txta" class, within the tr element).
The rest of code is unchanged.
Further notes:
Event handlers within event handlers (like $("textarea").keyup(function(){ ... $(".button").click(function() { ... ) should be avoided, since the effect is: each time an outer event is handled, a new handler for the inner event is created and attached.
Think of jquery as being kind of "navigation system" over DOM-tree. With functions like "closest", "find", "next", "prev" you navigate around and get to the desired element dynamically, at runtime.
When the desired object has ID and is unique, address it with "#ID" syntax.
When the desired object is repeated (like a row/cell within the table or an element within the cell), then use css-classes and DOM-traversal functions in order to address it.
If you need more information on DOM-traversing:
http://learn.jquery.com/using-jquery-core/traversing/
http://api.jquery.com/category/traversing/
My application has a list of indicators, each with its help button. Clicking on each button, brings up a ToolTipDialog with definition for each respectively. The way I have written the code (below), the content does not get refreshed when the user clicks on another help button within the list after having clicked the first one. I have not been able to figure out how to change the "content" dynamically. Any help will be appreciated:
HTML:
<div dojoType="dijit.layout.ContentPane" id="group1" title="Population projection" selected="true">
<table id="popIndTable">
<tr id="someID">
<td><input data-dojo-type="dijit.form.RadioButton" class="checkInd" id="checkCBR" name="checkInd" /></td>
<td id="indCBR">Crude Birth Rate</td>
<td id="infoCBR"><img id="imgCBR" src="Images/help_icon2.png" width="16px" onClick="showToolTipDialog(this,this.id);" /></td>
</tr>
<tr>
<td><input data-dojo-type="dijit.form.RadioButton" class="checkInd" id="checkTest1" name="checkInd" /></td>
<td id="indTest1">Test 1</td>
<td id="infoTest1"><img id="imgTest1" src="Images/help_icon2.png" width="16px" onClick="showToolTipDialog(this,this.id);" /></td>
</tr>
<tr>
<td><input data-dojo-type="dijit.form.RadioButton" class="checkInd" id="checkTest2" name="checkInd" /></td>
<td id="indTest2">Test 2</td>
<td id="infoTest2"><img id="imgTest2" src="Images/help_icon2.png" width="16px" onClick="showToolTipDialog(this,this.id);" /></td>
</tr>
</table>
</div>
JavaScript:
function showToolTipDialog(node,infoId){
var infoText;
var infoElem = dojo.byId(infoId).parentNode.id;
if (infoElem == "infoCBR"){
infoText = "This is the text container for CBR";
}
else if (infoElem == "infoTest1"){
infoText = "This is the text container for Test1";
}
if (!tooltipDialog) {
tooltipDialog = new dijit.TooltipDialog({
content: infoText,
style: "width:200px;height:auto;",
autofocus: !dojo.isIE, // NOTE: turning focus ON in IE causes errors when reopening the dialog
refocus: !dojo.isIE
});
dijit.popup.open({ popup: tooltipDialog, around: node});
tooltipDialog.opened_ = true;
}
else {
if (tooltipDialog.opened_) {
dijit.popup.close(tooltipDialog);
tooltipDialog.opened_ = false;
}
else {
dijit.popup.open({popup: tooltipDialog, around: node});
tooltipDialog.opened_ = true;
}
}
}
I believe the preferred way to change the value of a dojo widget programatically is to use the .set() method. ie:
this.myTooltipDialog.set("content", newContent);
Rather than:
this.myTooltip.content = newContent;
It looks like you never reset the content of your tooltipDialog. You create it once, but once it's created (new dijit.TooltipDialog({...})) it remains static.
I don't know the Dojo API. But can you just set the content value directly? Perhaps immediately after your first else:
tooltipDialog.content = infoText;
This is just a guess, but if Dojo's API is simple enough, that might do the trick.
If not, you might have to remove your if (!tooltipDialog) { check.
If your content is not too complicate, I suggestion you create a new TooltipDialog every call and clear it when blur, like
var dlgDiv = dojo.create("div");
var dlg = new dijit.TooltipDialog({
content: dlgDiv,
onBlur: function () {
popup.close(this);
this.destroyRecursive();
}
});
// you can create any content within dlgDiv at here dynamicly
dojo.popup.open({
around: yourArondNode ,
orient: ["below", "before", "after", "above"],
popup: dlg
});
dlg.focus();