How identify a secondary Id of a html element with multiple IDs - javascript

In my project, one of the jsp pages have this html structure:
<table id="hor-minimalist-a" class="campos">
<thead>
<tr>
<th>Campo</th>
<th>#</th>
</tr>
</thead>
<tfoot>
<tr>
<td> <input type="text" name="nome_campo"> </td>
<td> <button type="button" id="incluir_campo" class="btn btn-link">Incluir</button> </td>
</tr>
<tr>
<td> <div id="result_incluir_campo"></div> </td>
<td> <div id="result_excluir_campo"></div> </td>
</tr>
</tfoot>
<c:forEach var="item_key" items="${campos}">
<tr id="linha_campo_${item_key}">
<td> <input type="text" value="${item_key}"> </td>
<td> <button type="button" id="excluir_campo_${item_key}" class="btn btn-link">Excluir</button> </td>
</tr>
</c:forEach>
</table>
Note the line:
<button type="button" id="excluir_campo_${item_key}" class="btn btn-link">Excluir</button>
I have one jquery function associated to it:
<c:forEach var="item_key" items="${campos}">
<script>
$("#excluir_campo_${item_key}").on("click", function () {
$.ajax({
type: "GET",
url: "<c:out value="${pageContext.request.contextPath}/key/remove_campo"/>",
cache: false,
data: {nome: "${item_key}"}
}).done(function(data){
if(data == "yes") {
$("#linha_campo_${item_key}").remove();
}
else if(data == "not"){
$("#result_excluir_campo").empty().append("erro");
}
else {
$("#result_excluir_campo").empty().append("sem acesso");
}
});
});
</script>
</c:forEach>
I was using jstl, but i am facing some problems with this solution, since my list can be updated dynamicly.
Take in consideration I change the Id from this element:
<button type="button" id="excluir_campo_${item_key}" class="btn btn-link">Excluir</button>
to this two (separating the two "terms" of current Id):
excluir_campo ${item_key}
is there any way to detect the secong id with a jquery function similar to that:
$("#excluir_campo").on("click", function () {
var second_id = ???;
$.ajax({
type: "GET",
url: "<c:out value="${pageContext.request.contextPath}/key/remove_campo"/>",
cache: false,
data: {nome: "<second_id>"}
}).done(function(data){
if(data == "yes") {
$("#linha_campo_<second_id>").remove();
}
else if(data == "not"){
$("#result_excluir_campo").empty().append("erro");
}
else {
$("#result_excluir_campo").empty().append("sem acesso");
}
});
});
Or there is another way to accomplish the same result of the code above?

First of all, never generate scripts in rendered html using any kind of loops. What if you have 1000 items? 1000 times your code, very inefficient. You can use write a generic function and render that caller. This way, you save thousands of lines!
Secondly, NEVER use generated id's and id based functions, never ever! you can just use a generic class for that functionality, you do not need id selector. You just need an extra attribute like "key":
<div class="my-functionality" data-key="15" />
<div class="my-functionality" data-key="16" />
<div class="my-functionality" data-key="17" />
<div class="my-functionality" data-key="18" />
And you can just use either generated scripts in loops or jquery's each selector to bind events to your elements: you can wrap your click event like:
$('.my-functionality').each(function(index, elem){
$(elem).click(function(){
//do you stuff here!
var key = $(elem).data('key'); //this will read data-key attribute
});
});

Related

How to remove HTML table at form submitting

I have HTML table with dynamically generated contents. A td in the table contains a form. What I want is to remove the table from the page once this form is submitted because another page will be included at form submitting. I am using ajax and php. How can I amend my code below to remove the table once the form is submitted?
JAVASCRIPT
function chk(item_id){
$.ajax({
type:"post",
url:"edit_form.php",
data: {
id: item_id,
name: $('#name-'+item_id).val()
},
cache:false,
success: function(html){
$('#msg').html(html);
}
});
$('#forms').click(function(){
$('#table').hide();
});
return false;
}
HTML
<div id="msg"></div>
<div id="table">
<table align="center">
<tbody>
<tr>
<th>S/N</th>
<th>Subject</th>
<th>Edit</th>
</tr>
<tr>
<td><?php echo $i;?></td>
<td><?php echo $subject;?></td>
<td>
<form id="myform">
<input type="text" id="name-<?php echo $item_id;?>" hidden name="name" value="<?php echo $item_id;?>" >
<button type="submit" id="forms" onclick="return chk(<?php echo $item_id;?>)">Edit</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
$('#forms').click(function(){
$('#table').hide();
});
At the moment, when the form submits, the above code means you're creating an event handler to listen for the next time the button is clicked, which would then hide the table at that time.
To hide it as soon as the form is submitted, then simply remove the event handler part and just write
$('#table').hide();
by itself within the "chk" function.
N.B. If you don't want it to hide until after the ajax call is completed successfully, then move it inside the "success" function.
According to your question title:
You can simply add these lines in your ajax success: :
$("#table table").remove();
OR
You can set innerHTML of div to empty
$("#table").html("");
I hope this should work.
why do you need a <form> tag anyway? a more simple approach which doesn't involve jQuery
HTML
<input name="" />
<button id="submit">Submit</button>
JS
submit.onclick = function(){
element = document.querySelector('holderClass');
element.style.display = 'none'; // or any element
// ...ajax here
}
you might need document.querySelector()
//In success block you can remove the table by using $('#table').html("");
function chk(item_id){
$.ajax({
type:"post",
url:"edit_form.php",
data: {
id: item_id,
name: $('#name-'+item_id).val()
},
cache:false,
success: function(html){
$('#msg').html(html);
$('#table').html("");
}
});
return false;
}

How do I display data back from a javascript calling a php function?

I'm using a MVC framework and in my view I have my javascript code
this is in my view:
<script>
$(document).ready(function(){
$(document).on('click','#filtr',function(){
var id_val = $('#id_val').val();
var key_val= $('#key_val').val();
console.log(id_val);
console.log(key_val);
$.ajax({
url:"<?php echo base_url()?>filter/filtr",
method:"POST",
data:{
id_val:id_val,
key_val:key_val
},
/*beforeSend:function(){
$("container_tab").html("Searching...");
},*/
success:function(data){
$("container_tab").html(data);
}
})
});
});
</script>
<div class="table-responsive">
<table class="table table-striped table-hover" id="dataTables-example">
<tr>
<td>
Filter by...
</td>
<td>
ID: <input type="text" id="id_val" name="id_val" value="3" />
</td>
<td>
KEY: <input type="text" id="key_val" name="key_val" value="asdf12" />
</td>
<td>
<button type="button" class="btn btn-info btn-sm" id="filtr">FILTER</button>
</td>
</tr>
<br />
<div id="container_tab"></div>
</table>
</div>
I want the table that comes back from my controller to fill <div id="container_tab"></div>
in my filter controller I have my filtr function, but this function for now does not return $filter_list even though I'm still not doing the actual query.
public function filtr(){
$filter_list = '';
$filter_list .= '
<tr>
<td style="vertical-align: middle;" class="text-center">this should be sent to view as a table row</td>
</tr>
';
echo $filter_list;
}
when I do a console.log within my javascript function the values '3' and 'asdf12' are display but I'm not getting anything back on screen from my controller function calling filtr.
There is a minor error in your success function, your containor has a id called container_tab so use a # in front of its name like this
success:function(data){
$("#container_tab").html(data);
}

Editable multiple forms on a table

I am using editable plugin to preform in place edit
This is the code I am using that I got from their Doc page, it is supposed to be used for adding new records, But I want to use it to modify records)
<script>
$(document).ready(function() {
//init editables
$('.myeditable').editable({
url: '/post',
placement: 'right'
});
//make username required
$('#new_username').editable();
//automatically show next editable
$('.myeditable').on('save.newuser', function(){
var that = this;
setTimeout(function() {
$(that).closest('td').next().find('.myeditable').editable('show');
}, 500);
});
//create new user
$('#save-btn').click(function() {
$('.myeditable').editable('submit', {
url: '/newuser',
ajaxOptions: {
dataType: 'json' //assuming json response
},
success: function(data, config) {
if(data && data.id) { //record created, response like {"id": 2}
//set pk
$(this).editable('option', 'pk', data.id);
//remove unsaved class
$(this).removeClass('editable-unsaved');
//show messages
var msg = 'New user created! Now editables submit individually.';
$('#msg').addClass('alert-success').removeClass('alert-error').html(msg).show();
$('#save-btn').hide();
$(this).off('save.newuser');
} else if(data && data.errors){
//server-side validation error, response like {"errors": {"username": "username already exist"} }
config.error.call(this, data.errors);
}
},
error: function(errors) {
var msg = '';
if(errors && errors.responseText) { //ajax error, errors = xhr object
msg = errors.responseText;
} else { //validation error (client-side or server-side)
$.each(errors, function(k, v) { msg += k+": "+v+"<br>"; });
}
$('#msg').removeClass('alert-success').addClass('alert-error').html(msg).show();
}
});
});
//reset
$('#reset-btn').click(function() {
$('.myeditable').editable('setValue', null)
.editable('option', 'pk', null)
.removeClass('editable-unsaved');
$('#save-btn').show();
$('#msg').hide();
});
});
</script>
And this is the html
<tr>
<td>adel</td>
<td></td>
<td></td>
<td></td>
<td><img src=""></img></td>
<td width="10%"><button id="save-btn" class="btn btn-primary btn-sm">Ok</button><button id="reset-btn" class="btn btn-sm pull-right">Reset</button></td>
</tr>
<tr>
<td>sdqsd</td>
<td></td>
<td></td>
<td></td>
<td><img src=""></img></td>
<td width="10%"><button id="save-btn" class="btn btn-primary btn-sm">Ok</button><button id="reset-btn" class="btn btn-sm pull-right">Reset</button></td>
</tr>
<tr>
<td>dzadz</td>
<td>from me with love</td>
<td>anywhere</td>
<td>http://justawebsite.com</td>
<td><img src=""></img></td>
<td width="10%"><button id="save-btn" class="btn btn-primary btn-sm">Ok</button><button id="reset-btn" class="btn btn-sm pull-right">Reset</button></td>
</tr>
Now everything works fine, Except if I edit one of the 2 first rows and hit Ok It will send the details of the last form http://justawebsite.com and sometimes it doesn't send anything, It is really messed up and I spent hours reading te documentation but I couldn't figure out the problem
As I said in my comment, you've got different elements with the same id, so the selectors won't work (id must be unique). Put them as class instead:
<tr>
<td>
adel
</td>
<td>
</td>
<td>
</td>
<td>
</td>
<td>
<a href="#" class="myeditable picture" data-type="text" data-name="picture" data-original-title="Enter Picture">
<img src="" />
</a>
</td>
<td width="10%">
<button class="btn btn-primary btn-sm save-btn">Ok</button>
<button class="btn btn-sm pull-right reset-btn">Reset</button>
</td>
</tr>
Here's a fiddle to get you started https://jsfiddle.net/virginieLGB/k2of9xor/1/
On there, you'll see that I've selected the editable elements you want to submit.
$('.save-btn').click(function() {
var that = $(this);
var allEditables = that.parents("tr").find(".myeditable"); // all ".myeditable" elements in the same "tr" as the ".save-btn" that was clicked on
allEditables.each(function() {
// here I've kept your code because I don't know what happens in your file, but maybe you need a bulk action
$(this).editable('submit', {
...
I don't know how your PHP file works, so don't know how you save your user and if you need to submit all fields at once or not. If so, you'll have to modify my answer a bit.
Have you tried refreshing it afterwards?
For me i noticed, that as soon as it was refreshed i got the result that i have been expecting, but only for one of them. However, i couldn't solve the problem yet.
Please let me know what kind of result you get.
Otherwise try debugging...disable one of the first rows and try it again..

How to achieve partial rendering in spring mvc

Below is the html code
<select name="userSelected" id="ddl">
<option value="-1">---Select---</option>
<c:forEach items="${users}" var="user" varStatus="status">
<option value="${user.userId}">${user.userName}</option>
</c:forEach>
</select>
<button type="button" onclick="showForm(this)">view</button>
<div id="test">
<form:form id="expenseView"
action="${pageContext.request.contextPath}/deleteExpense"
method="POST" modelAttribute="users">
<table>
<thead>
<tr>
<td align="justify"></td>
<td align="justify"><b>Item</b></td>
<td align="justify"><b>Amount</b></td>
<td align="justify"><b>ExpenseDate</b></td>
</tr>
</thead>
<c:forEach items="${expenseList}" var="list" varStatus="status">
<tr>
<td><input type="checkbox" name="check"
value="${list.expenseId}"></td>
<td>${list.itemDescription}</td>
<td>${list.amount}</td>
<td>${list.expenseDate}</td>
</tr>
</c:forEach>
</table>
<input type="submit" value="Delete">
</form:form>
</div>
And this is the jquery, ajax am using
var hideResult = function() {
$('#test').hide();
};
var showResult = function() {
$('#test').show();
};
function showForm(myFormType) {
var selectedValue = $('#ddl option:selected').val();
var url = "${pageContext.request.contextPath}/viewExpense" + "?Id="
+ selectedValue;
$.ajax({
url : url,
}).success(function(data) {
$('#test').html(data);
});
showResult();
}
what I want to achieve is when a user hits a view button the only the div section should be refreshed so for that I am using ajax, but as my controller is sending a view name so what its doing is that it is refreshing that part only but with that one more of same kind of dropdown gets added.
Maybe, because my controller is sending the whole view. So how to achieve partial rendering of view. Please help
There are 2 approaches you can use.
You could adjust what is sent based on a parameter in the request or parse the response for the html that you want once it is received.
Here's how to do second approach
$.ajax({
url : url,
}).success(function(data) {
var $form = $(data).find('#expenseView');
$('#test').html($form);
});
You can also use replace the above with load() shorthand method of $.ajax to do this:
$('#test').load(url +' #expenseView');// note that space before selector is important

jQuery Multiple Dynamic Forms + Foreach Loop

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/

Categories

Resources