Click function in Django form - javascript

I have no idea how can I solve my problem. I have Django template with two models. I put these models in inlineformset_factory.
Example
DhcpConfigFormSet = inlineformset_factory(Dhcp, IPRange, extra=1)
and I displayed this form in template like this pictures
form http://sphotos-h.ak.fbcdn.net/hphotos-ak-prn1/601592_10151469446139596_1335258068_n.jpg
I want implement event, when I click on plus stick (marked field on pictures), show one more row (ip initial field, ip final field and delete check box).
I tried to do it on this way :
$(document).ready(function() {
$(".plusthick-left").click( function() {
var tr= $(".sort-table").find("tbody tr:last").length;
$(".sort-table").find("tbody tr:last").after($(".sort- table").find("tbody tr:last").clone())
});
but I have problem, because I just made copy of last row and took same attributes values?
My question is : How can I make new row, and set all attributes with values of last row increased by one.
For example:
<input type="text" id="id_ip_initial_0_ip_range">
This is field that generated form in template, and I want make field with id value like this:
<input type="text" id="id_ip_initial_1_ip_range">
How can I do it? :)

Related

Retrieve values of input fields from a table containing input fields as its data?

Scenario :
I have a table containing input fields and the number of input fields are not fixed, it can any number as the table is being rendered everytime based on what data user wants from the database.
So, every the table is rendered,each row of table has 5 input fields
as :
<input name="t-1">
<input name="r-1">
<input name="q-1">
<input name="s-1">
<input name="p-1">
The next row of table has again 5 input fields simliar to first row but the count number in the name for each input filed is incremented by 1.
<input name="t-2">
<input name="r-2">
<input name="q-2">
<input name="s-2">
<input name="p-2">
So for each row , the count number is incremented by 1 as per row number.
The user can modify and post the table to update database.
Todo :
I want to retrieve values of all these input fields while the form table is posted for updation.
Is there any easy way to achieve this ?
Please suggest.Thank You.
I think the easiest way to do add a class to every input you're interested in. For example data-field.
So each input would look like this
<input class="data-field" name="...">
Then just loop through them adding the values to whatever data structure you'd like to use, here I'll just use a list
var data = [];
$(".data-field").each((index, element) => {
data.push(element.value);
})
You can then perform whatever server request you need to make using the contents of data as your payload.
However, if you intend to just use a HTML form. Just ensuring that all inputs are within the form body and have name fields which are unique should suffice.
They should be automatically included in your form's payload.
Hope this helps.
querySelectorAll is your friend.
It allows you to leverage CSS selectors:
document.querySelectorAll("input[name*='-1']") for querying the first row
document.querySelectorAll("input[name*='r-']") for querying the first column
See fiddle.
No classes were harmed.

Cannot select table row id using jquery after ajax update

I have a html table containing data rows. I am building add/edit/delete functionality to the table using AJAX.
The format of my table row is as follows:
<tr id="281"><td class="todo-task">fdgdg</td><td>some more data</td><td>EDIT BUTTON</td></tr>
At the moment I have a working AJAX function to both add a new row and edit a row via a prepend().
In order to edit a table row, you click the edit button which pulls the values into the form and submits ... simples so far. Here's the code for the edit click and the form markup. Note the id from the edit click goes into a hidden field in the form.
$("button.edit-todo").bind("click", function(){
var task = $(this).closest('tr').children('td.todo-task').text();
var todoID = $(this).closest('tr').attr("id");
$("div#todo-form input.todo-task").val(task);
$("div#todo-form input.key").val(todoID);
});
...
<form id="mgnt-edit-todo-form" class="record-edit-form">
<input type="text" class="todo-task input" name="task">
<input class="key" name="key" type="hidden" value="279">
<button class="update uk-button uk-modal-close" type="submit">Save</button>
</form>
... and the ajax bit which binds the hidden field for the update.
$("button.update").bind("click", function(e){
var key = $(this).closest('.key').attr('value');
$.ajax({
type: "POST",
url: "update-record.php",
//etc etc etc
The problem
The first update works fine, it will prepend a table row including the id. The issue occurs when I then wish to make a further update to that same "prepended" row. Whilst the DOM shows the markup as correct the function on button.edit-todo will no longer get the id. When looking at the form markup in the DOM, the value of the hidden field is blank.
I've looked at the source in Chrome and I can see that it does not match the view in the browser/DOM. For example, the markup is all the same, but the rows have been put into a different order - it looks as though by date. (There is a date field but I have cut down the fields for this example..) I think this is causing the issue ... question is why? and how do i fix it?
Thanks
Update
Here is my markup in the DOM, looks fine to me.
To be absolutely clear the issue is occuring when clicking the edit button.
It calls the following function (now using 'on':
$("button.edit-todo").on("click", function(){
//load the data from this row
var task = $(this).closest('tr').children('td.todo-task').text();
var client = $(this).closest('tr').children('td.todo-client').text();
var due = $(this).closest('tr').children('td.todo-due').text();
var todoid = $(this).closest('tr').attr('id');
$("div#todo-form input.todo-task").val(task);
$("div#todo-form select").val(client);
$("div#todo-form input.todo-due").val(due);
$("div#todo-form input.key").val(todoid);
});
Clicking row 286 works as intended (it was present on the page load) in that the tr id is added to the hidden field in the form. Clicking row 297 (as far as I'm aware in the DOM?) does not pass the id to the hidden field...
Please help!!! Doing my head in...!
Instead of .bind use .on:
$("button.edit-todo").on("click", function(){
(...)
and
$("button.update").on("click", function(e){
(...)
Using ID for loaded data is not very comfortable way anymore. Use class instead of ID.
Also jQuery has changed "bind" to "on" method. I recommend to use "on".
For example:
$(document).on("click", ".edit-todo", function(){
var task = $(this).closest('tr').children('.todo-task').text();
var todoID = $(this).closest('tr').attr("id");
$(".todo-form .todo-task").val(task);
$(".todo-form .key").val(todoID);
});
Also, source shows the code when the document loads, not the dynamic DOM.

How to align form fields within a table for inline editing?

I am developing a webapp using Spring, jsp, javascript, jquery.
I display a table using datatables.
When I click on a table row I want it to change all fields to an inline edit inputs, selects etc. In addition I want to show some extra input fields in the next row and a save button.
Now I see several ways of doing this. I am not sure which one to take.
I can get a handle to selected row and then iterate over the td and transform them to input/select fields. I can then insert an extra row for the new fields and the save button.
I don't see this as a clean solution. I will have to issue a Post manually instead of using the Spring ModelAttribute binding for the form. (Can I still use ModelAttribute here?)
I can create an edit form in a jsp file which looks like:
<form:form action="" commandName="">
<td> <input ... > </td>
<td> <select ... > </td>
</tr>
<tr>
<td> <label> <input new field> </td>
<td> <button> </td>
</tr>
Note I do not have a beginning in a jsp file as I plan to reuse the tr from the existing row in the table.
This way I would be able to have a clean form and also use the update method I have already written which binds the form to a Java class. Also I do not have to bother about the alignment of input fields with the column names.
The generated html looks like
...
The problem with this approach is the placement of form element in the html causes the entire form to be cramped into one cell of the table which does not look good and messes up the whole layout. Is there a way out? Should I just replace the contents of the table with a having a colspan and then put divs inside this element and fine tune the css to ensure that the input fields align with the column names in the table?
Is there a better solution you can suggest?
In case the question is not very clear I can fill in more details.
This is what I would do (coming from a server-side development background, as I know developers love easy solutions)
Wrap the table with a single form
on Edit row (clicking row) open an ajax request that returns pure html that looks like the exact tr, only with whatever extra you want to include:
<tr><td><input type="text" name="text1" ... /></td><td>second row... </td></tr>
<tr><td colspan="2">And hey, here is more, and the save button ... </td></tr>
in jQuery replace tr with content retrieved (myTr.replace($(ajaxResponse))) or something similar
now Save button is a regular submit for the form
if you want to submit via ajax, once done, return the old html in your ajax response and replace the two trs with the old tr (you just need to hook it by giving new trs an attribute that you can find easily in jquery)
don't forget to switch off a global key to prevent double editing, users can edit one row at a time
Update: adding a second solution to dump load on client instead of server
To avoid overloading the server (though I wouldn't be worried about it until it becomes a regular habit), you can make your form fields as a template inside your HTML and use string replacement (or jQuery Templates), so instead of ajaxing to get response in step 2, you call the template, and replace the strings with attributes you save in every row... like this:
<div id="myTemplate"> // or you can use jQuery script templates
<tr><td><input type="text" name="${Name}" ... /> id is ${Id}</td><td>${SecondRow}... </td></tr>
<tr><td colspan="2">Save button here.... and may be more text ${MoreText}</td></tr>
</div>
in every row in your code add sufficient attributes or ids to know what you want to replace with, like this:
<tr data-itemid="34"><td ><input type="text" name="text1" id="findme" ... /></td><td data-moretext="here is more text">second column </td></tr>...etc
so now in your replacement script:
$("#myTemplate").html().replace("${Name}", $(thisrow).find("#findme").attr("name"))
.replace("${Id}",$(thisrow).attr("data-itemid"));
etc...
Of course after submission it has to be a to server, but in case user "cancels" you can have another readonly template
By the way, that is the way I usually go with, I use jQuery templates, and create edit and view templates, but I also repeat edit forms and I use jQuery ajax submit manually... but that... my friend, is not a simple clean and maintainable solution I'm afraid
I've been into an issue like this a year before. This is a messy problem. Either way if you traverse each td of row and convert it into text field or You can create a separate jsp file for this.
But the best in this case is to change the content of td to input field and post the data manually. because in this case you cannot wrap form tag around tr. You have to manually post the values of each input field.
P.S The very best solution is to create an edit dialog.
There is another solution, but I'm under the impression you won't like it very much... you can use a single form for the whole datatable (wrapping the whole table in a form is permitted) generate input fields for the current row and if it's updated submit the form asyncronously with javascript and restore td contents to the original html, if you name your fields such as name="field[]" you can also submit multiple rows at a time (I don't know if you'd want that though).
You can write html code such as
<form action="">
<table>
<tr><td><input type="hidden" name="row[]" value="1"/><input name="field[]"/></td></tr>
<tr><td>field value for row2</td></tr>
<tr><td><input type="hidden" name="row[]" value="3"/><input name="field[]"/></td></tr>
</table>
</form>
you can just grab the form with jquery and submit it via xmlhttprequest as I suspect you would if each row was a separate form (which is illegal), if you don't want multiple rows, just remove the [] and submit each row
and upon submitting the values you get them numbered correctly, don't know exactly how it would behave in java but in php I'd get the following:
$_GET[row][0] = 1;
$_GET[field][0] = 'value typed in row1';
$_GET[row][1] = 3;
$_GET[field][1] = 'value typed in row3';
Alternative table definition to avoid having the same name again
<form action="">
<table>
<tr><td><input name="field[1]"/></td></tr>
<tr><td>field value for row2</td></tr>
<tr><td><input name="field[3]"/></td></tr>
</table>
</form>
It's the same table as above only you set explicit indexes for each entry thus avoiding duplicate names in the response, preferrably use a unique identifier which can describe the row from the table that you're modifying in there (when possible I use the primary key) instead of the row number, just in case that wasn't clear enough.
Have you tried:
Wrap whole table in the form
have the data entries as disabled inputs with their borders hidden via CSS
when user clicks edit, enable the inputs and show the borders
You'll probably need hidden elements for each field
When user submits the form, post via ajax and set the inputs back to disabled with hidden borders
What about contenteditable?
Demo: http://jsfiddle.net/SO_AMK/XQekC/
jQuery:
var ctrlDown = false;
$(document).keydown(function(e) {
if (e.which = "ctrlKey") {
ctrlDown = true;
}
}).keyup(function(e) {
if (e.which = "ctrlKey") {
ctrlDown = false;
}
});
$('#example').dataTable();
$("#example tr").click(function() {
if ($(this).hasClass("row_selected") && ctrlDown) {
submitRow($(this));
return false; // Break out so the next if doesn't run
}
else if ($(this).hasClass("row_selected") && ctrlDown == false) {
return false; // Break out so the next if doesn't run
}
if ($(this).siblings(".row_selected").length && ctrlDown == false) {
$(this).siblings(".row_selected").each(function() {
submitRow($(this));
});
}
$(this).addClass("row_selected");
$(this).children("td").each(function() {
$(this).attr("contenteditable", true);
});
});
function submitRow(elm) {
var data = [];
$(elm).removeClass("row_selected").children("td").each(function() {
data.push($(this).text());
});
alert(data); // This will stop the keyup from firing, but you won't (I hope) really be using alerts
}​
This has everything but a submit-to-server function, it's also completely inline and has support for selecting multiple rows.
The only bug is, when it shows the data alert the focus goes off of the main window so the keyup event never fires, since you probably won't be using alerts this shouldn't be an issue. To fix it in the fiddle, press and release ctrl after the alert closes before clicking a row.
I see couple of problems
Your no. Of columns in the table & the edit columns you show are different
You might not be having complete data to edit the row so you might need to do an Ajax call and get it
If you have complete data on then you don't need point 2, let's assume you have a function f called with the clicked tr as the parameter
function f(row)
{
var newRow = yourTable.insertRow(parseInt(row.rowIndex,10)+1);
//you can place the above or below the clicked row , or you can even make the row visible false And then show the new row
Var newCell = newRow.insertCell(0);
newCell.colspan = 6;//the count if columns in your table row
NewCell.innerHTML = " put your HTML content here";
}

Dynamically created inputs with if else checkbox and multiple field validation

When the user clicks add more options, a from is created with javascript document.getElementById('addmore').innerHTML... It works great to display the form multiple times. I added a unique number each time to create unique IDs for each of the fields for submission. I have a checkbox that, if checked, needs to display another fields to get filled out:
document.getElementById('addmore').innerHTML += '<p><div class="required">*Type of Folder</div><label for="it09" class="hidelabel">Content Drive</label><input name="request['+fields+'][Type of Folder:]" id="cbpathCDB'+fields+'" type="checkbox" value="Content Drive" class="required" /><strong>Content Drive</strong> (A: drive)<br /><div id="pathCDB'+fields+'"><label for="newpathCDB"><span class="req">*Path to Content Drive Folder</span></label><input name="request['+fields+'][Path to Content Drive Folder:]" type="text" id="npcdb'+fields+'" size="50" class="required"/><br /><small>Path of folder to be created on Content Drive (A: drive)<br><em>(example: A:\drivefolder</em></small><br /></div></p>';
I have tried multiple ways (jquery included) of getting the next div, pathCDB+fields, to show when the checkbox is checked. It works fine without the +fields in there... see http://jsfiddle.net/kuVzV/4/ however, when I add the fields it fails to show/hide with the checkbox.
When the form is created though, the div doesn't show at first, just like it shouldn't... so I know the ID is correct. According to Firebug it is showing the correct ID with the field showing the correct # that is create...
I am at a loss right now.
Any suggestions on how to show/hide this div if the checkbox is checked for multiple inputs created dynamically?
Try checking out jQuery .show() and Jquery .hide(). I believe this is what you are looking for.
$(document).ready(function(){
$("#cbpathCDB1").on('click', $("#cbpathCDB1 input[type=checkbox]").is(":checked"), someFunction);
});
function someFunction(event){
if (event.target.checked){
$("#pathCDB1").hide('slow');
}
else{
$("#pathCDB1").show('slow');
}
}​
jsfiddle http://jsfiddle.net/FERMIS/7ThtT/6/ Here is an example with multiple fields.

How to create an OnChange "totaling" function from an unknown number of text fields

I'm having trouble figuring out how to do a simple Javascript task on fields in a table created with Rails 3.
My table has characteristic rows that the user adds using a form below (which updates the database and reloads the table partial).
The number of columns in the table is based on the number of attributes submitted in a different form. No matter how many columns are in a row, there is also a Total column after them. Each cell in the table has a text_field input, with an ID that is based on the row object id and the column object id.
What I'm trying to do is create an OnChange event for each of those cells, so that when a field value changes, the Total column gets updated with the total value in the text_field inputs of all cells in that row.
I don't know how to pass the Rails objects to Javascript (so I can cycle through the IDs), I can't figure out how to get the DOM element names and values if I use an action in the controller, and I don't know how to use RJS to do this either. Can anyone offer any help on how to do this? Thank you!
Sarah
If you use jQuery, you can set a class on the textboxes and listen to the change event on it.
example:
<input type="text" id="WhateverXXX" class="MyValue" />
<script type="text/javascript">
$(function(e) {
$('.MyValue').change(function(e) {
// update the total
});
});
</script>
In jQuery it'd be easy to iterate over all elements with the same class, so proper design of your document will help here.
Maybe something like this:
$('.thing_to_change').live('change', function() { retotal(); });
Your retotal function can be similar:
var total = 0;
$('.thing_to_change').each(function() { total = total + $(this).val() });

Categories

Resources