I am currently learning web development using Flask. I am stuck at a place where I want to use a jquery function to return the value from an input tag in for that corresponding row.
Here;s my HTML:
enter code here
{% extends "base.html" %} {% block title %} Menu item {% endblock %} {% block content %}
<div class="container">
<div class="row">
<table class="table table-striped table-inverse table-responsive">
<thead class="thead-inverse">
<tr>
<th>Item Name</th>
<th>Amount</th>
<th></th>
</tr>
</thead>
<tbody>
<form>
{% for item in menu_category %}
<tr>
<td scope="row">{{item.item_Name}}</td>
<td>{{item.item_Price}}</td>
<td>
<input type="hidden" class="form-control test" name="item_id{{ loop.index0 }}" id="itemID" placeholder="" value="{{ item.item_Id }}">
<a name="add_to_cart" id="add_to_cart" class="btn btn-primary clsAddToCart" href="#" role="button">Add to Cart</a>
</td>
</tr>
{% endfor %}
</form>
</tbody>
</table>
</div>
<p id=result>cart: </p>
</div>
{% endblock %}
Here's my Jquery function:
<script>
$(function() {
$('.clsAddToCart').bind('click', function() {
$.getJSON('{{ url_for("func_add_to_cart") }}', {
productID: $("input[name^='item_id']").val(),
}, function(data) {
$("#result").html(data.result);
});
return false;
});
});
</script>
I just want the function to return the corresponding item id on the button click, but somehow it always returns the first item id only for all.
Much Thanks!
The jQuery documentation for the val method explains this on the very first line:
Get the current value of the first element in the set of matched elements or set the value of every matched element.
(the emphasis is mine to show the relevant part for your question).
For each "add to cart" button to work on the corresponding input, you can use $(this) to get hold of the specific button clicked on, and then use, for example, the prev method (since in your HTML the input is the immediately preceding sibling - there are slightly more sophisticated things you could do to make this more robust to changes in your HTML, but I'll let you figure those out if you need them):
$(function() {
$('.clsAddToCart').bind('click', function() {
$.getJSON('{{ url_for("func_add_to_cart") }}', {
productID: $(this).prev().val(),
}, function(data) {
$("#result").html(data.result);
});
return false;
});
});
You are setting all input elements the same id ('itemID'). Should be like: 'item{{ item.item_Id }}'. May be this can solve your problem.
Your jQuery function should be like :
<script>
$(function() {
$('.clsAddToCart').bind('click', function() {
$.getJSON('{{ url_for("func_add_to_cart") }}', {
productID: $(this).closest('input').val(), //<==
}, function(data) {
$("#result").html(data.result);
});
return false;
});
});
</script>
In order to get the value of the correct input element you have to make use of the context of the click event. The this keyword refers to the element that was click. Therefore you can use that to target the correct input element using relative positioning to this. Per your structure any of the following should be fine as a replacement for $("input[name^='item_id']").val():
$(this).siblings().val(); //OR
$(this).closest('td').find('input').val(); //OR
$(this).parent().children('input').val(); //AND SO ON AND SO FORTH
Please remember that:
.bind() is deprecated as of v3, so use .on()
Keep all your id attributes unique and, no need to have them if you don't need them.
$(function() {
$('.clsAddToCart').on('click', function() {
console.log( $(this).siblings().val() );
/*$.getJSON('{{ url_for("func_add_to_cart") }}', {
productID: $("input[name^='item_id']").val(),
}, function(data) {
$("#result").html(data.result);
});
return false;*/
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<table class="table table-striped table-inverse table-responsive">
<thead class="thead-inverse">
<tr>
<th>Item Name</th>
<th>Amount</th>
<th></th>
</tr>
</thead>
<tbody>
<form>
<!--{% for item in menu_category %}-->
<tr>
<td scope="row">Item Name 1</td>
<td>100</td>
<td>
<input type="hidden" class="form-control test" name="item_id-1" id="itemID1" placeholder="" value="id1">
<a name="add_to_cart" id="add_to_cart" class="btn btn-primary clsAddToCart" href="#" role="button">Add to Cart</a>
</td>
</tr>
<tr>
<td scope="row">Item Name 2</td>
<td>200</td>
<td>
<input type="hidden" class="form-control test" name="item_id-1" id="itemID2" placeholder="" value="id2">
<a name="add_to_cart" id="add_to_cart" class="btn btn-primary clsAddToCart" href="#" role="button">Add to Cart</a>
</td>
</tr>
<tr>
<td scope="row">Item Name 3</td>
<td>300</td>
<td>
<input type="hidden" class="form-control test" name="item_id-1" id="itemID3" placeholder="" value="id3">
<a name="add_to_cart" id="add_to_cart" class="btn btn-primary clsAddToCart" href="#" role="button">Add to Cart</a>
</td>
</tr>
<tr>
<td scope="row">Item Name 4</td>
<td>50</td>
<td>
<input type="hidden" class="form-control test" name="item_id-1" id="itemID4" placeholder="" value="id4">
<a name="add_to_cart" id="add_to_cart" class="btn btn-primary clsAddToCart" href="#" role="button">Add to Cart</a>
</td>
</tr>
<!--{% endfor %}-->
</form>
</tbody>
</table>
</div>
<p id=result>cart: </p>
</div>
Related
I have an HTML table with some jinja(inside the value attribute).
my template:
<form class="" method="POST">
{% csrf_token %}
<table class="table table-hover my-5">
<thead class="">
<tr>
<th>No</th>
<th>Name</th>
<th>rank</th>
<th>gmail</th>
<th>Delete?</th>
</tr>
</thead>
<tbody class="my_dynamic_table">
{% for i in report_tableA %}
<tr>
<td>i</td>
<td><input type="text" name="name" value="{{ i.name }}"></td>
<td><input type="text" name="rank" value="{{ i.rank }}"></td>
<td><input type="email" name="gmail" value="{{ i.gmail }}"></td>
<td><i class="fa fa-times-circle" style="font-size: 22px; color: red;"></i></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row mx-5">
<button class="btn btn-warning">Add row</button>
<button type="Submit" class="btn btn-primary ml-auto">Submit</button>
</div>
</form>
Now my problem is how can I implement the functionality of the Add row button and the Delete icon(inside last td)? Here Add row function will add a new row inside the table also with a blank value attribute.
I have practiced it before by the following stackoverflow link. but now the problem is jinja is also added here.
I will be very grateful if you help me to fix this out.
You can first clone tr whenever Add row button is clicked then use find("input").val("") to empty value attribute and find("td:eq(0)").text(length) to add new i value to first td . Now , when remove is clicked then just use .closest('tr') this will get closest tr and remove that tr . Also, you need to adjust i value again inside your td so use .each loop to iterate through trs and change it.
Demo Code :
$(".add").on("click", function() {
//get length of tr
var length = $(".my_dynamic_table tr").length + 1
console.log(length)
//clone first tr
var cloned = $(".my_dynamic_table tr:first").clone();
$(cloned).find("input").val(""); //empty values of all cloned inputs
$(cloned).find("td:eq(0)").text(length); //add `i` value
$(cloned).appendTo($(".my_dynamic_table")) //append to tbody
})
//onclick of remove button
$(document).on("click", ".remove", function() {
$(this).closest("tr").remove(); //remove tr
//loop through tr
$(".my_dynamic_table tr").each(function(i) {
$(this).find("td:eq(0)").text((i + 1)) //change `i` value
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="" method="POST">
<table class="table table-hover my-5">
<thead class="">
<tr>
<th>No</th>
<th>Name</th>
<th>rank</th>
<th>gmail</th>
<th>Delete?</th>
</tr>
</thead>
<tbody class="my_dynamic_table">
<tr>
<td>1</td>
<td><input type="text" name="name" value="{{ i.name }}"></td>
<td><input type="text" name="rank" value="{{ i.rank }}"></td>
<td><input type="email" name="gmail" value="s#gmail.com"></td>
<td><i class="fa fa-times-circle remove" style="font-size: 22px; color: red;">x</i></td>
</tr>
</tbody>
</table>
<div class="row mx-5">
<button class="btn btn-warning add" type="button">Add row</button>
<button type="Submit" class="btn btn-primary ml-auto">Submit</button>
</div>
</form>
Trying to wrap my head around this for a while now. Some guru needs to help me out, it would be greatly appreciated. I don't know why it is not working.
$(".form").on('submit', function(event) {
event.preventDefault(); //prevent the forms default action
var surname = $(this).find(".surname");
console.log(surname);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<form class="form" method="post" action="nextpage.php">
<tr>
<td class="name">john</td>
<td class="surname">smith</td>
<td>british</td>
<td><button type="submit" class="btn btn-info btn-sm">Submit</button></td>
</tr>
</form>
<form class="form" method="post" action="nextpage.php">
<tr>
<td class="name">bob</td>
<td class="surname">doe</td>
<td>american</td>
<td><button type="submit" class="btn btn-info btn-sm">Submit</button></td>
</tr>
</form>
</table>
So if i click on the first submit button i should see john, and the second, bob.
As statet in the comments your HTML semantics is wrong. That's the first reason why it doesn't work. The second thing is you might want to use jQuerys .text() to get the "value" of a HTML element.
To make it work, see the example <table> element is now moved inside the <form> element. Depending on your needs this is one possible solution.
$(".form").on('submit', function(event) {
event.preventDefault(); //prevent the forms default action
var surname = $(this).find(".surname");
console.log(surname.text()); // here .text() is the only change in your js code
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="form" method="post" action="nextpage.php">
<table>
<tr>
<td class="name">john</td>
<td class="surname">smith</td>
<td>british</td>
<td><button type="submit" class="btn btn-info btn-sm">Submit</button></td>
</tr>
</table>
</form>
<form class="form" method="post" action="nextpage.php">
<table>
<tr>
<td class="name">bob</td>
<td class="surname">doe</td>
<td>american</td>
<td><button type="submit" class="btn btn-info btn-sm">Submit</button></td>
</tr>
</table>
</form>
Read more about permitted elements inside the <table> element here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table
Read more about permitted elements inside <form> tag here:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form
I fixed your code:
The <form> wraps around the <table>
Catch the clicks on <buttons> and get the surname relatively to the clicked row (<tr>)
$("button[type=submit]").on('click', function(event) {
event.preventDefault(); //prevent the forms default action
var surname = $(this).closest('tr').find(".surname");
console.log(surname.text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="form" method="post" action="nextpage.php">
<table>
<tr>
<td class="name">john</td>
<td class="surname">smith</td>
<td>british</td>
<td><button type="submit" class="btn btn-info btn-sm">Submit</button></td>
</tr>
<tr>
<td class="name">bob</td>
<td class="surname">doe</td>
<td>american</td>
<td><button type="submit" class="btn btn-info btn-sm">Submit</button></td>
</tr>
</table>
</form>
JSFiddle: https://jsfiddle.net/v9k3sL1f/
just put the class="form" and action inside the tr tag and it'll works.
i'm trying to submit a modal to the controller, and doing a #foreach loop but when i try to send the id of the corresponding item's id, it sends the last value of the id, always = 13 :-
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach($categories as $category)
<tr>
<td>{{ $category->id }}</td>
<td>{{ $category->name }}</td>
<td>
<button class="myBtn btn btn-primary">Edit</button>
<button class="btn btn-danger">Delete</button>
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
so when i press on the edit button it always sends the last value of the id not the corresponding one
<form action="{{ route('category.update', $category->id) }}" method="post">
<div>
<label for="name">Name:</label>
<input type="text" id="Category Name" name="name">
</div>
<button type="submit" class="bn btn-success">Save</button>
{{ csrf_field() }}
</form>
Write onlick function which ll set route to your form:
<button data-url="{{ route('category.update', $category->id) }}" class="myBtn btn btn-primary" onclick="changeRoute({{ route('category.update', $category->id) }})">Edit</button>
Write this in your script, but you need to give id to your form as myForm
<script>
function changeRoute(url) {
alert(url);
$("#myForm").attr("action",url);
}
$(".myBtn").click(function() {
var url = $(this).attr("data-url");
console.log(url);
$("#myForm").attr("action",url);
});
</script>
I have a table with some rows and each tow has an data-key value. Now I select one of those rows and want to click on a button in order to forward this data-key value as an GET value. I don't really know how to capture this selected data-key. Kindly asking for help.
Here is a fiddle: fiddle
Below is my snippet so far.
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid">
<div class="form-horizontal" style="margin-top:5em;">
<div class="input-group">
<input class="form-control form-control-sm" id="FunctionBookSearchForEvents" placeholder="Search for Events" style="font-size:12px;">
<button class="btn btn-sm btn-secondary" href="events.phtml?TableID=''" data-id="" style="margin-left:1em; font-size:12px;">Add Event</button>
</div>
<div id="Table">
<table class="table table-sm table-hover">
<thead>
<tr>
<th>ID</th>
<th>Event Name</th>
</tr>
</thead>
<tbody>
<tr class="clickable-row" data-key="12">
<td>12</td>
<td>Test Event 12</td>
</tr>
<tr class="clickable-row" data-key="13">
<td>13</td>
<td>Test Event 13</td>
</tr>
</tbody>
</table>
</div>
</div>
You could try to implement this code.
I will add modified version of your code, but I will mark out where I modified it.
<div class="container-fluid">
<div class="form-horizontal" style="margin-top:5em;">
<div class="input-group">
<input class="form-control form-control-sm" id="FunctionBookSearchForEvents" placeholder="Search for Events" style="font-size:12px;">
<button class="btn btn-sm btn-secondary" href="events.phtml?TableID=''" data-id="" onclick="addEvent();" style="margin-left:1em; font-size:12px;">Add Event</button>
</div>
<div id="Table">
<table class="table table-sm">
<thead>
<tr>
<th>ID</th>
<th>Event Name</th>
</tr>
</thead>
<tbody>
<tr onclick="test(this);"> // MODIFIED, This line would be added onto all your rows that you want clickable.
<td>12</td>
<td>Test Event 12</td>
</tr>
<tr onclick="test(this);">
<td>13</td>
<td>Test Event 13</td>
</tr>
</tbody>
</table>
</div>
</div>
Now I will show you the implementation of the function test.
function test(element){
console.log(element.innerHTML);
}
Now, you could do anything with this element callback. For example, you could store it in a variable and send that to a PHP page using AJAX, when you press a button.
Edit 1
First, I want to point out that you cannot use <button> as a link.
First, there are a few modifications to the HTML.
<button id="submitButton" class="btn btn-sm btn-secondary" onclick="addEvent();" data-id="" style="margin-left:1em; font-size:12px;">Add Event</button>
Here we added an id, "submitButton" and an onclickEvent which will call the function addEvent.
This is the function addEvent:
function addEvent(){
if(currentRow == undefined){
alert("Select a row");
return;
}
var link = "events.phtml?TableID="+currentRow.cells[0].innerHTML;
}
This link variable can easily be implemented using an AJAX call with jQuery or just plain javascript.
Sidenote
The function test has also been edited.
function test(element){
currentRow = element;
}
I recommend editing the name on the function test so that the code will look more organised.
Edit 2
If I have understood what you want out of this, this will be the new fix.
So you will have to edit the HTML again.
<div class="container-fluid">
<div class="form-horizontal" style="margin-top:5em;">
<div class="input-group">
<input class="form-control form-control-sm" id="FunctionBookSearchForEvents" placeholder="Search for Events" style="font-size:12px;">
<button class="btn btn-sm btn-secondary" href="events.phtml?TableID=''" data-id="" onclick="addEvent();" style="margin-left:1em; font-size:12px;">Add Event</button>
</div>
<div id="Table">
<table class="table table-sm">
<thead>
<tr>
<th>ID</th>
<th>Event Name</th>
</tr>
</thead>
<tbody>
<tr onclick="test(this);" data-key="12"> // MODIFIED, This line would be added onto all your rows that you want clickable.
<td>12</td>
<td>Test Event 12</td>
</tr>
<tr onclick="test(this);" data-key="13">
<td>13</td>
<td>Test Event 13</td>
</tr>
</tbody>
</table>
</div>
</div>
You will need to make a slight change to the javascript as well.
function addEvent(){
if(currentRow == undefined){
alert("Select a row");
return;
}
var link = "events.phtml?TableID="+currentRow.getAttribute("data-key");
}
You still use this address for anything you like, for example an AJAX request.
I have a list of elements in a table. If a button is clicked a modal pops up and to show some content in that modal i need to get the id of the element that was clicked. How can i do that?
<div id="collapseOne" class="accordion-body collapse">
<div class="accordion-inner">
<form action="" method="post">
<table class="table">
<thead>
<tr>
<td width="25%"><strong>Options</strong></td>
<td width="25%"><strong>Block id</strong></td>
<td width="25%"><strong>Block type</strong></td>
<td width="25%"><strong>Block order</strong></td>
</tr>
</thead>
<tbody>
<tr>
<td>
<button data-toggle="modal" id="editBlockBtn" data-target="#editBLock" data-block-id="8" class="btn btn-warning btn-mini"></button>
<button data-toggle="modal" id="editBlockBtn" data-target="#deleteBlock" data-block-id="8" class="btn btn-danger btn-mini"></button></td>
<td>8</td>
<td>image</td>
<td>1</td>
</tr>
<tr>
<td>
<button data-toggle="modal" id="editBlockBtn" data-target="#editBLock" data-block-id="9" class="btn btn-warning btn-mini"></button>
<button data-toggle="modal" id="deleteBlockBtn" data-target="#deleteBlock" data-block-id="9" class="btn btn-danger btn-mini"></button></td>
<td>9</td>
<td>image</td>
<td>2</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
You can just write the ID again into a data-attribute on each button. Then you have easy access using jquery's data method. Like so:
PHP:
<button data-toggle="modal" data-target="#editBLock" data-block-id="<?php echo $block['id']; ?>" class="btn btn-warning btn-mini"><i class="icon-edit icon-white"></i></button>
JavaScript:
$('button').click(function() {
var clickedId = $(this).data('block-id');
});
If you can not change your PHP code, and the structure in your table is fixed, you can do it like this:
$('button').click(function() {
var clickedId = $(this).parent().next('td').text();
});
first: id="" is Unique, You can not use it twice in two elements. so change These to classes: editBlockBtn and deleteBlockBtn.
so if you want to get the <td>'s content It is better to add them a class like:
<td class="Block-id">9</td>
<td class="Block-type">image</td>
<td class="Block-order">2</td>
now You can easily get the closest() <tr> parent (or just use parent()):
$('.editBlockBtn').click(function() {
var parentTr = $(this).closest('tr');
});
then you can get the content:
var block_id = parentTr.find('.Block-id').text();
var block_type = parentTr.find('.Block-type').text();
var block_order = parentTr.find('.Block-order').text();
demo: http://jsfiddle.net/gbpkxbvv/