Obtain current row from button click - javascript

I've been trying to read a particular value from a row of display that I have on my php webpage. The idea is I am trying to get the current value of the certain cell in the row, however, I've tried using getElementsByTagName does not work, as I can not access the value afterwards (only has HTMLCollection object). I am using closest, but this only works and gets the beginning row.
EDITED:
Does not seem to pop up anything. Well the modal does pop up, but no alerts.
Tried this demo but did not work either haha...
<td><button class='sellButton btn btn-primary' data-target='#modalsell' id='sellStock'>Sell Stock</button></td>
<div id="modalsell" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Sell Stocks</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form role="form">
<div class="form-group">
<div class="input-group">
<label for="shares" class="input-group-addon glyphicon glyphicon-user">Amount of Shares:</label>
<input type="text" class="form-control" id="sharess" placeholder="Shares Selling...">
<label for="start" class="input-group-addon glyphicon glyphicon-user">Minimal Sell Price:</label>
<input type="text" class="form-control" id="starts" placeholder="(0 for No Limit)" value="0">
<label for="stop" class="input-group-addon glyphicon glyphicon-user">Max Sell Price:</label>
<input type="text" class="form-control" id="stops" placeholder="(0 for No Limit)" value="0">
</div> <!-- /.input-group -->
</div> <!-- /.form-group -->
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-toggle='modal' onclick="sellStock()">Place Sell</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
undefined elements in invoker
$(document).ready(function(){
$(".sellButton").on('click', function (e) {
alert('test 1');
$('#modalsell').modal('toggle', $(this));
});
$('#modalsell').on('show.bs.modal', function(button){
alert('test 2');
var $invoker = $(button.relatedTarget);
alert($($invoker).id);
});
});

Issue :
the main issue with your code is you are using same id in loop (id='sellStock'). This is the reason you are getting same tr on clicking any button.
Note : id attribute should be unique inside page.
Solution :
Try this code for getting parent tr of clicked button.
<th><button onclick="myFunction(this)">Sell Stock</button></th>
your handler function :
function myFunction(elem) {
var x = elem.parentElement.parentElement; // x is the parent row
//rest of your code goes here
}
Alternative :
You can also use class selector instead of id which is a better option.
update as per comment request :
you can use get the invoker element of modal by doing this. #your-modal is your modal selector, you can use class or id as per your requirement.
$('#your-modal').on('show.bs.modal', function (e) {
var $invoker = $(e.relatedTarget);
//rest of code
});
instead of :
alert($($invoker).id);
use this :
alert($($invoker).attr('id'));
Happy Coding!

Jquery solution
First Case:
If you want whole row of table then you have to identify your table using some unique class or Id.
Lets say if your table unique class name is "table-responsive" then you can get all row of table using
$(".table-responsive").find('tbody tr');
It will give you rows of tbody.
Second case:
If you want to get row of current click button(in this case sellStock) button then you can use parents in context of this on button click.
Example:
From #Touheed Khan answer:
Don't use id if you are generating multiple element in loop dynamically.
you can use class, otherwise it will get only first element.
Let's say if your button class name is rowButton then you can use it
as like below.
$(".rowButton").click(function() {
var currrentRow =$(this).parents('tr');
});
thanks #Touheed Khan.

use class and TD
"<tr>
<td>". $arrayval"</td>
<td class='need'>"."(Need)"."</td>
<td>".$arrayval."</td>
<td>".$arrayval."</td>
<td>".$arrayval."</td>
<td><button class='sellStock btn btn-primary' data-toggle='modal' data-target='#modal1'>Sell Stock</button></td>
</tr>";
use jQuery consistently
$(".table").on("click",".sellStock",function() {
var cellContent = $(this).closest("tr").find(".need").text();
});
or
$(".table").on("click",".sellStock",function() {
var row = $(this).closest("tr");
// handle row here
});

Related

Update asp-route-id with jQuery

I'm building a razor pages application, and I want to use a modal as a partial view.
Foreach loop from where I'm opening the modal:
#foreach (var item in Model.SourceFiles)
{
<tr>
<td>#item.Id</td>
<td>#item.FileName</td>
<td>#item.Created</td>
<td>
#(item.IsConverted == true ? "Exported" : "Imported")
</td>
<td>
<button type="submit" class="btn btn-primary" asp-page-handler="FileContent" asp-route-fileId="#item.Id">View</button>
</td>
<td>
#if ((await authorizationService.AuthorizeAsync(User, "DeletePolicy")).Succeeded)
{
Delete
}
</td>
</tr>
}
I'm trying to set a new value of an asp-route-id tag using javaScript (jQuery), but I cant get it to work.
function triggerDeleteModal(itemId) {
$('#' + 'deleteModal').modal('toggle');
$("#confirmDeleteButton").attr('asp-route-deleteid', itemId)
}
Modal (partial view):
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteModalTitle">Caution!</h5>
</div>
<div class="modal-body">
<p style="white-space: pre-wrap;">#Model.DeleteModalText</p>
<p></p>
</div>
<div class="modal-footer">
<button type="submit" id="confirmDeleteButton" class="btn btn-secondary" data-bs-dismiss="modal">Yes</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
</div>
</div>
</div>
</div>
When pressing the yes-button (#confirmDeleteButton) in the modal to submit the form, the id is not getting passed in the asp-route-deleteid tag helper, and the id is always 0 in the OnPost-method.
Code behind where deleteid always is 0:
public async Task<IActionResult> OnPostAsync(int deleteid)
{
//code for deleting stuff
}
When trying to console.log the value of any attribute besides asp-route tags, the value is shown. When trying to log the value of an asp-route tag, the value is undefined.
Any ideas of how I can get the asp-route-deleteid to be passed to the code behind?
BR
The asp-route-* attribute works on tag helpers, which are server-side components. It is not rendered to the browser and is inaccessible to JavaScript. It is designed to work with elements that have an href, action or formaction attribute, and it either adds the attribute value to the query string of the generated href, or as a URL segment depending on the route template for the target page.
Generally, you shouldn't pass POST data within the URL, so instead, you can wire up a click event handler to the confirmDeleteButton that initiates an AJAX post that passes the deleteid:
$('#confirmDeleteButton').on('click, function(){
$.post('/yourpage',{deleteid: itemId}, function(){
// process the call back
})
})

Change a variable when a link is clicked

I have a page that loads the last 25 rows from a database and displays them in a table. I want to be able to click a link and have a modal popup that contains more information. I've got everything working except for knowing which row Id was clicked. Below is currently what I have. Model.ClickedId never changes from the default value so the popup has the same message everytime.
How can I make it so ClickedId on the backend is set to item.Id when the link is clicked?
Backend:
public int ClickedId { get; set; } = 0;
Front end:
#foreach (var item in Model.SFException)
{
<tr>
<td>
View <!-- Set ID to item.ID? -->
</td>
<td>
#Html.DisplayFor(modelItem => item.ObjectType)
</td>
<td>
#Html.DisplayFor(modelItem => item.ObjectKeyProperty)
</td>
<td>
#Html.DisplayFor(modelItem => item.ObjectKeyValue)
</td>
...
And the modal code where I am trying to display more information:
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterTitle">Exception Details</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
#Html.DisplayFor(model => model.SFException[Model.ClickedId].StackTraceErrorMessage)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
There are a couple of ways I've done this in the past. Either:
Get all the information that all rows need and dump it on the page (maybe in hidden elements), then when the user interacts with your rows show/hide the relevant extra information. Depending on how much extra info you need there can be a bit of overhead with this.
Put the 'StackTraceErrorMessage' on the page somewhere like
<td class="open-modal" data-itemId="#item.Id">
View
<input type="hidden" value="#item.StackTraceErrorMessage" />
</td>
Then in JS look for when the 'View' text is clicked, move the StackTraceErrorMessage from the hidden area to the modal html and display the modal html
$(document).ready(function() {
$(".open-modal").click(function() {
// get the item id from the clicked on element
var itemId = $(this).data("itemId");
// get the relevant StackTraceErrorMessage and put in the modal html
var message = $(this).find('input').val();
$('.modal-body').html(message);
// show the modal html (presumably this has styles associated to make it look like a dialog)
$('.modal).show();
});
)};
The second options is, put the basic information on the page and then when the user interacts with it go back to the server-side to request more details and then display that. There's a bit more back-and-forth and setup for this method.
The link in your row would look something like this:
<td data-itemId="#item.Id" class="show-row-details">View</td>
Where the item id is stored as an attribute in the element and a class is attached so we can watch for clicks.
In your js you would then look for any clicks like :
$(document).ready(function() {
$(".show-row-details").click(function() {
// get the item id from the clicked on element
var itemId = $(this).data("itemId");
// make a request to the backend for more info
$.ajax({
url: baseUrl + "YourController/YourAction",
data: { itemId : itemId },
success: function (data) {
// put the data returned into the popup element on our page and make it visible
$('#popup').html(data);
$('#popup').show();
}
})
});
)};
So to support this on your page you would need an elment ready to recieve data from the backend
<div id="popup" style="display:none"></div>
and also you would need a controller and action on your backend that is going to return the Html that you want to display in the popup div (pretty much just an action that loads a partial view (i.e. no layout) with your 'modal code' in it).
Note: I haven't actually tried the above code, so there may be some syntax errors etc

Bootstrap Modal Confirmation

I've got a table that displays user details per row along with a Remove button that launches a Bootstrap modal confirmation dialog box.
My goal is to have the confirmation button trigger an event which will delete that particular user.
How would I pass jsmith22 from the table row into my Javascript function?
HTML Table
<tr>
<td>jsmith22</td>
<td>John Smith</td>
<td>555-555-5555</td>
<td>test#gmail.com</td>
<td><button type="button" class="btn btn-default btn-lg btn-block roster-button active" data-toggle="modal" data-target="#removeUser">Remove</button></td>
</tr>
Modal dialog
<div aria-labelledby="myModalLabel" class="modal fade" id="removeUser"
role="dialog" tabindex="-1">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Remove Employee</h4>
</div>
<div class="modal-body">
<p>Are you sure you wish to remove this user?</p>
</div>
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal" type="button">Cancel</button>
<button class="btn btn-danger" id="remove-button" type="submit">Remove</button>
</div>
</div><!-- end modal-content -->
</div><!-- end modal-dialog -->
</div><!-- end modal -->
Javascript
// Remove button event trigger
$('#remove-button').click(function() {
$.post('/API/removeUser', {} );
});
Can do it with Bootstrap Modal event listener
Add data attribute data-id to modal trigger button
<td><button type="button" data-id="jsmith22" data-toggle="modal" data-target="#removeUser" class="btn btn-default btn-lg btn-block roster-button active">Remove</button></td>
Add input type="hidden" to modal and pass the id value to modal hidden input when shown
Hidden Input
<input type="hidden" id="RowId" value="">
Modal event show script
$(document).ready(function(){
$('#removeUser').on('show.bs.modal', function (e) {
var id = $(e.relatedTarget).data('id');
$('#RowId').val(id);
});
});
Now with click event
$('#remove-button').click(function() {
var delid = $('#RowId').val();
//Do what ever you like to do
$.post('/API/removeUser', {} );
});
Fiddle Example
Alternate Solution
You can skip the hidden input and create a global variable
Modal trigger button with data attribute data-id to modal trigger button
<td><button type="button" data-id="jsmith22" data-toggle="modal" data-target="#removeUser" class="btn btn-default btn-lg btn-block roster-button active">Remove</button></td>
Modal Event, Click function with Global variable script
$(document).ready(function() {
var delid = ''; //global variable
$('#removeUser').on('show.bs.modal', function(e) {
delid = $(e.relatedTarget).data('id'); //fetch value of `data-id` attribute load it to global variable
alert(delid);
});
$('#remove-button').click(function() {
alert(delid); //Use the global variable here to del the record
//Do what ever you like to do
//$.post('/API/removeUser', {} );
});
});
Alternate Solution Example
You can get the contents of the first td of the button's row with getting this:
var person = $(this).closest('tr').find('td').eq(0).html()
fiddle: https://jsfiddle.net/7j4bmgbv/

Carry the id of a row to modal

I have a table that is being populated dynamically from the database, In it there is a button on whose click i wish to display a modal, as the work is done in bootstrap so its not difficult to create a modal.
<table id="report" class="table table-bordered" >
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
<?
$sql="SELECT * from `request` ";
$result= mysqli_query($con, $sql);
if(mysqli_num_rows($result)>0)
{
while($row = mysqli_fetch_assoc($result))
{
$requestid = $row['requestid'];
?>
<tr>
<td><? echo $requestid; ?> </td>
<td><div href="javascript:;" class="btn btn-drank mb-10" data-toggle="modal" data-target="#myModal2">Detail</div></td>
<td> </td>
<td> </td>
</tr>
<?}
}
</table>
Table will look similar to this
Now the part where i am stuck is that i also wish to carry the requestid of the row whose corresponding detail button user has clicked to the modal, so that if user clicks on detail of first row, modal displays the data of first row, and when the user clicks on detail of second row, modal displays the data of second row and so on..
Code for modal is
<div class="modal fade" id="myModal2" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Details</h4>
</div>
// wish to get the request id and once i have it i can use it to fetch data
</div>
</div>
</div>
UPDATE
Adding this update on top because I feel this would be more elegant and easiest way.
No need of having Step 1 and Step 2 i.e. a global variable and click event for modal invoker. You can just have shown.bs.modal method and get the sourceElement i.e. element that invoked modal, and fetch id corresponding to that row as below:
$("#myModal2").on('shown.bs.modal',function(e){
var sourceElement=e.relatedTarget;
/*e.relatedTarget gives you which element invoked modal*/
var id=$(sourceElement).closest('tr').find("td:first").text();
/*using sourceElement you can easily fetch id
alert(id);
})
Updated DEMO
DEMO
3 steps:
Have a global variable to store id
Click event to all div whose data-target="#myModal" to fetch clicked row's id
Make use of modal's shown.bs.modal to get id obtained during click event
Step 1
var id=0; /*a global variable*/
Step 2
$("div[data-target=#myModal2]").on('click',function(){
id=$(this).closest('tr').find("td:first").text();
/*get the closest tr of clicked div and find first td which has id value and store it in
id variable*/
})
Step 3
$("#myModal2").on('shown.bs.modal',function(e){
alert(id);
/*since id is a global variable and it will get value as soon as click occurs
Fetch the data with above id*/
})
Add data-id="id of the row" in button
<button data-id="id of the row" class="btn btn-drank mb-10" data-toggle="modal" data-target="#myModal2">Detail</button >
Put a form tag and input type hidden in that form.
<div id="myModal2" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<form >
<input type="hidden" id="id">
<button type="submit" class="btn btn-danger">Delete</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</form>
</div>
</div>
</div>
</div>
Then in script do it with event show.bs.modal
$(document).ready(function () {
$('#myModal12').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget);//Button which is clicked
var clickedButtonId= button.data('Id');//Get id of the button
// set id to the hidden input field in the form.
$("input #id").val(clickedButtonId);
});
You can add a listener for show.bs.modal so you have a reference to the componet clicked by the user and to the modal, as stated in the documentation.
$('#myModal2').on('show.bs.modal', function (e) {
var modal = $(this);
var rowBtn = $(e.relatedTarget);
var row = rowBtn.closest('tr');
// Here you id for the clicked row
var rowId = row.find('td:first').text();
row.find('td').each(function(){
// Here you can iterate between each row cell
var cellCont = $(this).text();
// e.g. use cellCont to create modal content
});
// Here you can update modal content
// e.g. modal.find('.modal-body').html( your dynamic content );
});

Modal Form Submission without refresh

I have a modal window that pops up when I want to add a new project to my dashboard. I have gotten it to work with jquery post however, I cannot prevent it from refreshing. What I want to do is after the project is added to the database, show a success message and close the modal window after few seconds and not refresh the page (parent page of modal).
Here is my modal
<div class="modal fade" id="add-project-dialog" tabindex="-1" role="dialog" aria-labelledby="basicModal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="myModalLabel">Add a new Project</h4>
</div>
<div class="modal-body">
<h3>New Project:</h3>
<form class="form-horizontal" id="add-project-form" action="/projects/add" method="POST">
<fieldset>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="name">Project Name</label>
<div class="col-md-4">
<input id="name" name="name" type="text" placeholder="" class="form-control input-md">
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="description">Project Description</label>
<div class="col-md-4">
<input id="description" name="description" type="text" placeholder="" class="form-control input-md">
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="project_state">Project State</label>
<div class="col-md-4">
<input id="project_state" name="project_state" type="text" placeholder="" class="form-control input-md">
</div>
</div>
</fieldset>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="add-btn" class="btn" type="submit">Add</button>
</div>
</form>
</div>
</div>
Here is my project-dashboard.js
AddProject = function(){
$(document).ready(function() {
$("#submit").submit(function(event){
event.preventDefault();
$.ajax({
url: "/projects/add",
type:"POST",
data:
{
'name': $('#name').val(),
'description': $('#description').val(),
'project_state': $('#project_state').val()
}
});
});
});
}
My views.py
class AddProject(webapp2.RedirectHandler):
def get(self):
template_values = {
#'greetings': greetings,
#'url_linktext': url_linktext,
}
path = os.path.join(os.path.dirname(__file__), '../templates/project-add.html')
self.response.write(template.render(path, template_values))
def post(self):
project = Project()
project.name = self.request.get('name')
project.description = self.request.get('description')
project.project_state = self.request.get('project_state')
time.sleep(2)
project.put()
self.redirect('/projects')
I have tried removing the self.redirect('/projects') however that only takes me to a blank page that is /projects/add (that is the action in the form).
The issue is that you added .ready(foo) handler inside of the AddProject function. I suppose that document is loaded when AddProject is called.
Another issue is that in your HTML, the form has id add-project-form, so you should do $("#add-project-form") instead of $("#submit").
$(document).ready(function () {
$("#add-project-form").submit(function(event){
event.preventDefault();
$.ajax({
url: "/projects/add",
type:"POST",
data:
{
'name': $('#name').val(),
'description': $('#description').val(),
'project_state': $('#project_state').val()
}
});
});
});
});
Take ready handler outside of the AddProject function and it should work (the submit handler is added).
Edit: After some debugging, the answer was to use the right id and proper placing of the javascript code, as noted by the comments.
For starters, a refresh is easy to avoid, just make sure to prevent the default event from running; since you're using jQuery, I would recommend doing return false to end the function, since it both 'prevents default' and 'stops propagation'.
So the first thing you should do is check if your javascript code is actually running and not erring in the middle of execution. If everything is fine there, the worst case is that the project is not actually added (server side error) but the page should not refresh.
Your server side code has nothing to do with the refresh (if it's being properly hijacked), so the response doesn't really matter, I would actually return the id of the new project (so you could provide a link for the newly created item or something like that), but i digress...
Here is a snippet for not only closing modals without page refresh but when pressing enter it submits modal and closes without refresh
I have it set up on my site where I can have multiple modals and some modals process data on submit and some don't. What I do is create a unique ID for each modal that does processing. For example in my webpage:
HTML (modal footer):
<div class="modal-footer form-footer"><br>
<span class="caption">
<button id="PreLoadOrders" class="btn btn-md green btn-right" type="button" disabled>Add to Cart <i class="fa fa-shopping-cart"></i></button>
<button id="ClrHist" class="btn btn-md red btn-right" data-dismiss="modal" data-original-title="" title="Return to Scan Order Entry" type="cancel">Cancel <i class="fa fa-close"></i></a>
</span>
</div>
jQUERY:
$(document).ready(function(){
// Allow enter key to trigger preloadorders form
$(document).keypress(function(e) {
if(e.which == 13) {
e.preventDefault();
if($(".trigger").is(".ok")) //custom validation dont copy
$("#PreLoadOrders").trigger("click");
else
return;
}
});
});
As you can see this submit performs processing which is why I have this jQuery for this modal. Now let's say I have another modal within this webpage but no processing is performed and since one modal is open at a time I put another $(document).ready() in a global php/js script that all pages get and I give the modal's close button a class called: ".modal-close":
HTML:
<div class="modal-footer caption">
<button type="submit" class="modal-close btn default" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
jQuery (include global.inc):
$(document).ready(function(){
// Allow enter key to trigger a particular class button
$(document).keypress(function(e) {
if(e.which == 13) {
if($(".modal").is(":visible")){
$(".modal:visible").find(".modal-close").trigger('click');
}
}
});
});
Now you should get no page refreshes on any of your modals if u follow these steps.

Categories

Resources