// function to add set of elements
var ed = 1;
function new_server() {
ed++;
var newDiv = $('#server div:first').clone();
newDiv.attr('id', ed);
var delLink = '<a class="btn btn-danger" style="text-align:right;margin-right:65px" href="javascript:deled(' + ed + ')" > Delete server ' + ed + ' </a>';
newDiv.find('tr:first th').text('Server ' + ed);
newDiv.find('select:first').attr('id', 'cat' + ed);
newDiv.append(delLink);
$('#server').append(newDiv);
newDiv.find('input:text').val('');
web = new Array('CF9', 'CF10', 'CF11', 'ASP.NET', 'PHP', 'CMS', 'JAVA');
db = new Array('MSSQL Express', 'MSSQL Web', 'MSSQL Standard', 'MYSQL');
app = new Array('IMIS', 'TERMINAL', 'AD');
populateSelect();
$(function() {
$('#cat' + ed).change(function() {
populateSelect();
});
});
function populateSelect() {
cat = $('#cat' + ed).val();
$('#item').html('');
if (cat == 'Web') {
web.forEach(function(t) {
$('#item').append('<option>' + t + '</option>');
});
}
if (cat == 'DB') {
db.forEach(function(t) {
$('#item').append('<option>' + t + '</option>');
});
}
if (cat == 'App') {
app.forEach(function(t) {
$('#item').append('<option>' + t + '</option>');
});
}
}
alert(ed);
}
// function to delete the newly added set of elements
function deled(eleId) {
d = document;
var ele = d.getElementById(eleId);
var parentEle = d.getElementById('server');
parentEle.removeChild(ele);
//ed--;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="server">
<div id="1">
<table border="3">
<tbody>
<tr>
<th colspan="4" style="background-color:#b0c4de;">Server 1</th>
</tr>
<br>
<tr>
<td>Technology
<br>
<select name="tech[]" id="cat1">
<option value="">Select</option>
<option value="Web">Web</option>
<option value="DB">DB</option>
<option value="App">App</option>
<option value="O">Other</option>
</select>
<br>
<select id="item" name="techtype[]">
</select>
<br>
</td>
<td>CPU?
<input type="text" name="cpu[]">
<br>
</td>
<td>Memory?
<input type="text" name="memory[]">
<br>
</td>
<td>Disk Space?
<input type="text" name="space[]">
<br>
</td>
</tr>
<br><a class="btn btn-info" href="javascript:new_server()"> Add New Server </a>
<br>
</tbody>
</table>
</div>
</div>
I have a form as follows:
On page load I cannot update any of the select items.
If i add a new server It will then allow me to change the selects from the first,
If i create a third same result.
I think what is happening is my id's for the select are not changing an im not sure why, I put a JS alert at the bottom to verify that 'ed' is changing as it loops.
End result Im looking for it to be able to change the values of the select from the first and then when another server is added be able to change those select values with out changing any others and so on.
ANy help would be great.
You are using a counter to dynamically create ID's for your servers, so they look like $("#"+cat+counter).
Probleme is you also use your counter to impact lists in populateSelect(), that means you only modify list content of your last created server.
Here is a demo of what I understand of your projet, and a solution that I can give you.
Most changes are about this :
$(function () {
$(document).on("change", '.cat', function () {
populateSelect($(this).val, $(this).attr("id"));
});
});
And this :
function populateSelect(listValue, listID) {
var serverItem = $("#" + listID).closest(".tableServer").find('.item')
cat = $("#" + listID).val();
serverItem.html('');
...
You can see that I changed id="item" for class="item" (this way, cloned servers won't duplicat id="item").
I moved your arrays on top of your code to be reachable from every function
I also moved your populateSelect function and $(function() { outside the new_server() function
I added newDiv.find('.item').html(''); into new_server() function to not clone previously selected option.
I added class="tableServer" to table wrapper in order to dynamically target them in populateSelect()
Related
Preface:
I have an HTML table where user fills in Name and URL of social networks where they have account. Each row has a checkbox. With the help of jQuery and JavaScript, on pressing Add Row button, a row is dynamically added to the table and on pressing delete row button those rows are deleted for which checkbox is checked.
Objective:
When selected rows are deleted, I want to assign id to input elements and checkboxes of every remaining row in serial manner, so that the rows are always serially sound.
Problem:
I am not able to find what makes it throw error, as childNodes[] do not seem to lead to unavailable element. Please help!
Snippet:
// variable to keep track of rows(records)
var social_recs_num = 1;
$(document).ready(function () {
$("#social_add_rec").click(function () {
social_recs_num++;
var markup = "<tr> <th scope=\"row\"> <div class=\"form-group\"> <div class=\"form-check\"> <input type=\"checkbox\" class=\"form-check-input\" id=\"social_rec" + social_recs_num + "\" name=\"social_rec\"> <label class=\"form-check-label\" for=\"social_rec" + social_recs_num + "\"> " + social_recs_num + "</label> </div></div></th> <td> <div class=\"form-group shadow-sm\"> <label for=\"name_social" + social_recs_num + "\">Select or Type</label> <input type=\"text\" list=\"name_social" + social_recs_num + "\" class=\"form-control\" placeholder=\"Name\"> <datalist id=\"name_social" + social_recs_num + "\"> <option value=\"Wikipedia\">Wikipedia</option> <option value=\"Youtube\">Youtube</option> <option value=\"Facebook\">Facebook</option> <option value=\"Twitter\">Twitter</option> <option value=\"Pinterest\">Pinterest</option> </datalist> </div></td><td> <div class=\"form-group shadow-sm\"> <textarea class=\"form-control\" id=\"url_social" + social_recs_num + "\" cols=\"30\" rows=\"1\" placeholder=\"URL\"></textarea> </div></td></tr>"; //in case of id we need to do it like: "min_sysreq" +social_recs_num...as social_recs_num has been incremented priorly it will be the row number of row to be added
$("table tbody").append(markup);
});
// Find and remove selected table rows...only condition is that there must be present attribute name='sysreq_rec' in input element for checkbox of every row
$("#social_delete_rec").click(function () {
$("table tbody").find('input[name="social_rec"]').each(function () {
if ($(this).is(":checked")) {
social_recs_num = social_recs_num - $(this).length;
$(this).parents("tr").remove();
}
});
// to be run when a row is deleted...this assigns ids to input elements in serial manner
var table = document.getElementById("mytab1");
var rowCount = table.rows.length;
// i has been initiated with 1, as header row is the 0th row
for (var i = 1; i < rowCount; i++) {
var row = table.rows[i];
// on this line, getting error: `Uncaught TypeError: Cannot read property 'id' of undefined`
row.childNodes[0].childNodes[0].childNodes[0].childNodes[0].id = "social_rec" + i;
row.childNodes[0].childNodes[0].childNodes[0].childNodes[1].for = "social_rec" + i;
row.childNodes[0].childNodes[0].childNodes[0].childNodes[1].innerHTML = " " + i;
row.childNodes[1].childNodes[0].childNodes[0].for = "name_social" + i;
row.childNodes[1].childNodes[0].childNodes[1].list = "name_social" + i;
row.childNodes[1].childNodes[0].childNodes[2].id = "name_social" + i;
row.childNodes[2].childNodes[0].childNodes[0].id = "url_social" + i;
//iterate through rows
//rows would be accessed using the "row" variable assigned in the for loop
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered" id="mytab1">
<thead>
<tr>
<th scope="col">
#
</th>
<th scope="col">
Name
</th>
<th scope="col">
URL
</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">
<div class="form-group">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="social_rec1" name="social_rec">
<label class="form-check-label" for="social_rec1"> 1</label>
</div>
</div>
</th>
<td>
<div class="form-group shadow-sm">
<label for="name_social1">Select or Type</label>
<input type="text" list="name_social1" class="form-control" placeholder="Name">
<datalist id="name_social1">
<option value="Wikipedia">Wikipedia</option>
<option value="Youtube">Youtube</option>
<option value="Facebook">Facebook</option>
<option value="Twitter">Twitter</option>
<option value="Pinterest">Pinterest</option>
</datalist>
</div>
</td>
<td>
<div class="form-group shadow-sm">
<textarea class="form-control" id="url_social1" cols="30" rows="1" placeholder="URL"></textarea>
</div>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" type="button" id="social_add_rec">Add Row</button>
<button class="btn btn-primary" type="button" id="social_delete_rec">Delete Row</button>
P.S. :
I have used jQuery and Bootstrap.
this question seemed close, but I think I don't have the same mistake.
Edit:
I need to display(or store) inputs by user, for which I wrote following JavaScript code.
var social = function () {
var val = "social:\n";
for (x = 1; x <= social_recs_num; x++) {
//where social_recs_num is number of rows
val = val + "\s\s-\n";
val = val + "\s\s\s\s" + "name: " + getElementById("name_social" + x) + "\n";
val = val + "\s\s\s\s" + "url: " + getElementById("url_social" + x) + "\n";
}
return val;
}
function social returns the value input by user in YAML format. For this code, when selected rows are deleted, I want to assign id to input elements and checkboxes of every remaining row in serial manner.
The Problem:
The issues you are seeing is because you are trying to get the 'childNodes' property of an html element. In order to access that property, you would have to cast the element as a jQuery object by adding '$( )' around it. In this case, that would be '$(row)'.
However, if you do that with your code, you still get errors because of the mess of nested .childNodes[0]. You could get it working using that existing code, however...
Suggested Refactoring:
...As other stated, there are more elegant ways to approach this problem. There are a number of ways you could tackle it, but given your current html I would refactor to something like this:
//...
// to be run when a row is deleted...this assigns ids to input elements in serial manner
$('#mytab1 tbody tr').each(function() {
var rowNum = $(this)[0].rowIndex;
var formcheck = $(this).find('.form-check');
formcheck.find('.form-check-input')[0].id = 'social_rec' + rowNum;
formcheck.find('.form-check-label')[0].for = 'social_rec' + rowNum;
formcheck.find('.form-check-label')[0].innerHTML = ' ' + rowNum;
var formName = $(this).find('td')[0];
$(formName).find('label')[0].for = 'social_rec' + rowNum;
$(formName).find('input')[0].list = 'social_rec' + rowNum;
$(formName).find('datalist')[0].id = 'social_rec' + rowNum;
var formUrl = $(this).find('td')[1];
$(formUrl).find('textarea')[0].id = 'social_rec' + rowNum;
});
//...
This replaces your for loop with a jquery .each loop and then uses the .find() function to loop up each control you want to manipulate. You'll also note that it is using the rowIndex() function to determine what number to assign the row.
I think the advantage to using an approach like this is that it's much easier to read the code and determine what controls are being affected. You could also additionally refactor your html to use classes that are unique to the controls you want to target, then you could just use the class selector to change those controls.
Hope that helps!
I have a django form with an inline formset and I'd like to give the user the ability to add/remove the fields 'approach_type' and 'approach_number'
This a snippet of the form:
<div class="form-group">
<div class="input-group-sm">
<label class="text-muted">Approaches</label>
<div class="form-control pl-4 pt-2">
<div class="row form-row">
<input type="hidden" name="approach_set-TOTAL_FORMS" value="1" id="id_approach_set-TOTAL_FORMS" /><input type="hidden" name="approach_set-INITIAL_FORMS" value="0" id="id_approach_set-INITIAL_FORMS" /><input type="hidden" name="approach_set-MIN_NUM_FORMS" value="0" id="id_approach_set-MIN_NUM_FORMS" /><input type="hidden" name="approach_set-MAX_NUM_FORMS" value="1000" id="id_approach_set-MAX_NUM_FORMS" />
<input type="hidden" name="approach_set-0-id" id="id_approach_set-0-id" />
<div class="col pr-5>"><select name="approach_set-0-approach_type" class="form-control" id="id_approach_set-0-approach_type">
<option value="" selected>---------</option>
<option value="ILS">ILS</option>
<option value="CATII">CAT II</option>
<option value="CATIII">CAT III</option>
</select></div>
<div class="col pr-5>"><input type="number" name="approach_set-0-number" min="0" class="form-control" id="id_approach_set-0-number" /> </div>
<div class="input-group-append">
<button class="btn btn-success add-form-row">+</button>
</div>
<!-- <div class="col pr-5>"><input type="checkbox" name="approach_set-0-DELETE" class="form-control" id="id_approach_set-0-DELETE" /></div> -->
</div>
and here is the JS from this tutorial:
https://medium.com/#taranjeet/adding-forms-dynamically-to-a-django-formset-375f1090c2b0
<script type='text/javascript'>
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function cloneMore(selector, prefix) {
var newElement = $(selector).clone(true);
var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
newElement.find(':input').each(function() {
var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
total++;
$('#id_' + prefix + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
var conditionRow = $('.form-row:not(:last)');
conditionRow.find('.btn.add-form-row')
.removeClass('btn-success').addClass('btn-danger')
.removeClass('add-form-row').addClass('remove-form-row')
.html('<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>');
return false;
}
function deleteForm(prefix, btn) {
var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
if (total > 1){
btn.closest('.form-row').remove();
var forms = $('.form-row');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).find(':input').each(function() {
updateElementIndex(this, prefix, i);
});
}
}
return false;
}
$(document).on('click', '.add-form-row', function(e){
e.preventDefault();
cloneMore('.form-row:last', 'form');
return false;
});
$(document).on('click', '.remove-form-row', function(e){
e.preventDefault();
deleteForm('form', $(this));
return false;
});
</script>
This line is the current problem:
var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');
I'm sorry but I only know a very little bit of JS.
So as you pointed out in your comment the problem is that $(this).attr('name') is returning undefined. It looks like for some reason your query is also returning the button, which if you look at the jquery documentation makes a little sense... although i dont know if I would consider a button an input automatically but they do. I'm also not 100% sure what you want this to be doing, but to solve this issue you can either wrap that chunk of code in an if block checking if the name attr is undefined or not, changing your query on the inputs to be stricter, or filter down the list you are running over. Here is a codepen that I think is working as intended, but again, didn't read the whole meium article so no promises. the relevant part is here:
newElement.find(':input')
.filter(function(){
return $(this).attr('name');
})
.each(function(){
...
})
the filter function is essentially saying filter out all results where the name attribute is undefined.
let me know if this does what you're hoping for! good luck learning Javascript! I promise its more fun that what you're currently dealing with. especially if you start using ES6
I have a page that is essentially a table which has its rows duplicated when the button is pushed. Each additional row has a unique id/name.
I now have this problem. I essentially have a similar table on a different page. Main difference is that it may have additional inputs. At the moment, it looks something like this:
JavaScript
var cloned;
$(function() {
initDatepickersAndSelect();
$('#add_row').on('click', function(evt) {
addRow();
});
$('#delete_row').on('click', function(evt) {
deleteRow();
});
$('#add_row2').on('click', function(evt) {
addRow(x);
});
$('#delete_row2').on('click', function(evt) {
deleteRow(x);
});
});
function initDatepickersAndSelect() {
cloned = $("table tr#actionRow0").eq(0).clone();
$(".dateControl").datepicker({
dateFormat: "dd-mm-yy"
});
$(".responsibility").select2({
tags: true
});
$(".campaignType").select2({
tags: true
});
}
function addRow() {
var $tr = cloned.clone();
var newRowIdx = $("table#actionTable tr").length - 1;
$tr.attr('id', 'actionRow' + newRowIdx);
$tr.find("input, select").each(function(i_idx, i_elem) {
var $input = $(i_elem);
if ($input.is("input")) {
$input.val("");
}
$input.attr({
'id': function(_, id) {
return id + newRowIdx;
},
'name': function(_, name) {
return name.replace('[0]', '[' + newRowIdx + ']');
},
'value': ''
});
});
$tr.appendTo("table#actionTable");
$(".dateControl", $tr).datepicker({
dateFormat: "dd-mm-yy"
});
$(".responsibility", $tr).select2({
tags: true
});
$(".campaignType", $tr).select2({
tags: true
});
}
function deleteRow() {
var curRowIdx = $("table#actionTable tr").length;
if (curRowIdx > 2) {
$("#actionRow" + (curRowIdx - 2)).remove();
curRowIdx--;
}
}
HTML
<div class="col-md-12 noPadding">
<table class="table table-bordered table-hover additionalMargin" id="reportTable">
<thead>
<tr>
<th class="text-center">Something</th>
<th class="text-center">Something else</th>
</tr>
</thead>
<tbody>
<tr id='actionRow0'>
<td>
<select class="campType" name='reportInput[0][campType]' id="reportInput">
<option value=""></option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</td>
<td>
<input type="text" name='reportInput[0][campDelivery]' id="dateInput" class="form-control" />
</td>
</tr>
</tbody>
</table>
<a id="add_row" class="btn btn-default pull-right">Add Row</a>
<a id='delete_row' class="pull-right btn btn-default">Delete Row</a>
</div>
The last thing I want to do is duplicate all of my JavaScript and rename things to match the above.
What I am wondering, is there anyway I could reuse the JavaScript?
Any advice appreciated.
Thanks
(code also available as JSFiddle)
Based on my understanding of the question, I think you could do something like this. Assuming a function called addRow as seen in your fiddle, the first step is to include that JS on all pages where you want that functionality. You then mentioned that other pages might have additional controls. For this, I'd override the function...
On the page with normal controls
function addRow() {
// Row adding code...
}
On the page with extra controls
var oldAddRow = addRow;
var addRow = function(){
$('.some_other_control').click(ctrlHandler);
$('.some .input').val('');
oldAddRow();
}
I suggest to have an invisible "template row" in your table, which you can copy to add new rows.
Something like this:
<style>
tr.template { display: none; }
</style>
<table id="table1">
<tr class="template"><td><input id="blah">/td><td><input id="foo"></td></tr>
</table>
<button id="add">Add Row</button>
<script>
function add_row($table) {
var count = $table.find('tr').length - 1;
var tr_id = ""+(count+1);
var $template = $table.find('tr.template');
var $tr = $template.clone().removeClass('template').prop('id', tr_id);
$tr.find(':input').each(function() {
var input_id = $(this).prop('id');
input_id = tr_id + '_' + input_id;
$(this).prop('id', input_id);
});
$table.find('tbody').append($tr);
}
$('#add').on('click', function() { add_row($('#table1')); });
</script>
I think it will be easier to make the code generic in this way. If you don't want the inputs in the template to be submitted, you can disable them or remove them somehow.
Demo: http://sam.nipl.net/table-demo.html
You may just clone a row and reset attibutes within with something like:
function addRow(id) {
var c = $("table#"+id+" tr").last();
$("table#"+id+" tbody").append(c.clone().attr({id: "addedrow" + Math.random()*10+1}));
}
function deleteRow(id,index) {
var curRowIdx = $("table#"+id+" tr").length;
if (curRowIdx > 2) {
if(index != void 0) {
$("table#"+id+" tr")[index].remove();
}else{
$("table#"+id+" tr").last().remove();
}
}
}
Call it with
$('#add_row').on('click', function(evt){addRow("reportTable");});
$('#delete_row').on('click', function(evt){deleteRow("reportTable",1);});
Maybe you'll prepare new rows for your table with something like
var emptyRow[id] = $("table#"+id+" tr").last();
and change
$("table#"+id+" tbody").append(c.clone().attr({id: "addedrow" + Math.random()*10+1}));
to
$("table#"+id+" tbody").append(emptyRow[id].clone().attr({id: "addedrow" + Math.random()*10+1}));
My page is submitting straight away without checking for validation or displaying the alert. I believe the submit is firing early but is my issue that I have multiple forms?
My question is how can I get the submit to work as it should do where it checks the validation and if that is successful, display the confirmation?
I have had to post my whole code so that you can see the order of the code, because the order of the code maybe my downfall:
<script type="text/javascript">
$(document).ready(function () {
$('#sessionsDrop').change(function () {
$('#targetdiv').hide();
if ($(this).val() !== '') {
var text = $(this).find('option:selected').text();
var split = text.split(' - ');
$('#currentId').val($(this).find('option:selected').val());
$('#currentAssessment').val(split[0]);
$('#currentDate').val(split[1]);
$('#currentTime').val(split[2]);
} else {
$('#currentAssessment,#currentDate,#currentTime,#currentId').val('');
}
});
});
function validation(e) {
var isDataValid = true;
var moduleTextO = document.getElementById("modulesDrop");
var errModuleMsgO = document.getElementById("moduleAlert");
if (moduleTextO.value == "") {
$('#targetdiv').hide();
$('#assessmentForm').hide();
$('#choiceForm').hide();
$('#submitchoicebtn').hide();
errModuleMsgO.innerHTML = "Please Select a Module";
isDataValid = false;
} else {
errModuleMsgO.innerHTML = "";
}
if (isDataValid === false) {
if (e.preventDefault) {
e.preventDefault();
e.stopPropagation(); //VERY important
}
e.returnValue = false;
e.cancelBubble = true;
}
return isDataValid;
}
function choicevalidation() {
var isDataValid = true;
var currentAssesO = document.getElementById("currentAssessment");
var currentAssesMsgO = document.getElementById("currentAlert");
currentAssesMsgO.innerHTML = "";
if (currentAssesO.value == "") {
$('#targetdiv').hide();
currentAssesMsgO.innerHTML = "Please Select an Assessment to edit from the Assessment Drop Down Menu";
isDataValid = false;
} else {
currentAssesMsgO.innerHTML = "";
}
return isDataValid;
}
function showConfirm() {
var examInput = document.getElementById('curentAssessment').value;
var dateInput = document.getElementById('currentDate').value;
var timeInput = document.getElementById('currentTime').value;
if (choicevalidation()) {
var confirmMsg = confirm("Are you sure you want to take the following Assessment:" + "\n" + "Exam: " + examInput + "\n" + "Date: " + dateInput + "\n" + "Time: " + timeInput);
if (confirmMsg == true) {
submitform();
}
}
}
$('#choiceForm').on('submit', showConfirm);
</script>
<h1>TAKE AN ASSESSMENT</h1> //FORM 1
<form action="assessmentchoice.php" method="post" onsubmit="return validation(event);">
<table>
<tr>
<th>Module:
<select name="modules" id="modulesDrop">
<option value="">Please Select</option>
<option value="CHI2513_Systems Strategy_1">CHI2513 - Systems Strategy</option>
<option value="CHT2220_Interactive Systems_4">CHT2220 - Interactive Systems</option>
</select>
</th>
</tr>
</table>
<p>
<input id="moduleSubmit" type="submit" value="Submit Module" name="moduleSubmit"
/>
</p>
<div id="moduleAlert"></div>
<div id="targetdiv"></div>
</form>//FORM 2
<div id='lt-container'>
<form action='assessmentchoice.php' method='post' id='assessmentForm'>
<p id='warnings'></p>
<p><strong>Selected Module:</strong> CHI2513 - Systems Strategy
<input type='hidden'
value='1'>
</p>
<p><strong>Assessments:</strong>
<select name="session" id="sessionsDrop">
<option value="">Please Select</option>
<option value='28'>LDREW - 09-01-2013 - 09:00</option>
<option value='29'>BQNYF - 10-01-2013 - 10:00</option>
<option value='22' disabled>WDFRK - 17-01-2013 - 09:00</option>
<option value='26' disabled>POKUB1 - 25-01-2013 - 15:00</option>
</select>
</p>
</form>
</div>
<div id='rt-container'>//FORM 3 (This is where when submitted it should show confirmation)
<form
id='choiceForm' action='assessment.php' method='post'>
<p><strong>Chosen Assessment:</strong>
</p>
<table>
<tr>
<th></th>
<td>
<input type='hidden' id='currentId' name='Idcurrent' readonly='readonly'
value='' />
</td>
</tr>
<tr>
<th>Assessment:</th>
<td>
<input type='text' id='currentAssessment' name='Assessmentcurrent' readonly='readonly'
value='' />
</td>
</tr>
<tr>
<th>Date:</th>
<td>
<input type='text' id='currentDate' name='Datecurrent' readonly='readonly'
value='' />
</td>
</tr>
<tr>
<th>Start Time:</th>
<td>
<input type='text' id='currentTime' name='Timecurrent' readonly='readonly'
value='' />
</td>
</tr>
</table>
<div id='currentAlert'></div>
<p id='submitchoicebtn'>
<button id='choiceSubmit'>Choose Assessment</button>
</p>
</form>
here is a DEMO
try to change following line:
function showConfirm() { /* your existing code */ }
into
function showConfirm(e) {
e.preventDefault();
/* your existing code */
return false;
}
Have you already tried this:
function showConfirm(e) {
e.preventDefault();
var examInput = document.getElementById('curentAssessment').value;
var dateInput = document.getElementById('currentDate').value;
var timeInput = document.getElementById('currentTime').value;
if (choicevalidation()) {
return confirm("Are you sure you want to take the following Assessment:" + "\n" + "Exam: " + examInput + "\n" + "Date: " + dateInput + "\n" + "Time: " + timeInput);
}
return false;
}
$('#choiceSubmit').on('click', function(e) {
if (showConfirm(e)) {
$('#choiceForm').submit();
}
});
Your forms aren't nested so it shouldn't be because there are multiple.
Try removing all of the code in your validation function so that it only returns false:
function validation(e) {
return false;
}
If this works, you'll know the problem lies within your JavaScript and not the HTML. From there you can add back more and more of the function until you discover which part is causing the issue.
i think this line if ($(this).val() !== '') { should be like this if ($(this).val() != '') {
also as stated in another answers add this: e.preventDefault();
I would use the following code
$('#choiceSubmit').click(function(e) {
e.preventDefault();
var x = 0;
if (showConfirm(e)) {
$('#choiceForm').submit();
}
});
Have you used firebug or inspector (chrome/ie) and stepped through the javascript? In the above case, i'd add a breakpoint at the e.preventDefault() method. If it hits this, then the issue is within the javascript. if not then the javascript is not even bound to the submit button.
im very new at javascipt (im php developer) so im really confused trying to get this working.
In my web form i have 3 textfields (name, description and year) that i need to let the user add as many he needs, clicking on a web link, also, any new group of text fields need to have a new link on the side for removing it (remove me).
I tried some tutorial and some similar questions on stackoverflow but i dont get it well. If you can show me a code example just with this function i may understand the principle. Thanks for any help!
this is the simplest thing that has come to my mind, you can use it as a starting point:
HTML
<div class='container'>
Name<input type='text' name='name[]'>
Year<input type='text' name='year[]'>
Description<input type='text' name='description[]'>
</div>
<button id='add'>Add</button>
<button id='remove'>Remove</button>
jQuery
function checkRemove() {
if ($('div.container').length == 1) {
$('#remove').hide();
} else {
$('#remove').show();
}
};
$(document).ready(function() {
checkRemove()
$('#add').click(function() {
$('div.container:last').after($('div.container:first').clone());
checkRemove();
});
$('#remove').click(function() {
$('div.container:last').remove();
checkRemove();
});
});
fiddle here: http://jsfiddle.net/Fc3ET/
In this way you take advantage of the fact that in PHP you can post arrays: server side you just have to iterate on $_POST['name'] to access the various submissions
EDIT - the following code is a different twist: you have a remove button for each group:
$(document).ready(function() {
var removeButton = "<button id='remove'>Remove</button>";
$('#add').click(function() {
$('div.container:last').after($('div.container:first').clone());
$('div.container:last').append(removeButton);
});
$('#remove').live('click', function() {
$(this).closest('div.container').remove();
});
});
Fiddle http://jsfiddle.net/Fc3ET/2/
jsFidde using append and live
String.format = function() {
var s = arguments[0];
for (var i = 0; i < arguments.length - 1; i++) {
var reg = new RegExp("\\{" + i + "\\}", "gm");
s = s.replace(reg, arguments[i + 1]);
}
return s;
}
var html = "<div>" + '<input name="name{0}" type="text" />' + '<input name="description{1}" type="text" />' + '<input name="year{2}" type="text" />' + '<input type="button" value="remove" class="remove" />' + '</div>',
index = 0;
$(document).ready(function() {
$('.adder').click(function() {
addElements();
})
addElements();
$('.remove').live('click', function() {
$(this).parent().remove();
})
});
function addElements() {
$('#content').append(String.format(html, index, index, index));
index = index + 1;
}
Look at this: http://jsfiddle.net/MkCtV/8/ (updated)
The only thing to remember, though, is that all your cloned form fields will have the same names. However, you can split those up and iterate through them server-side.
JavaScript:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$("#addnew").click(function(e) {
$("#firstrow").clone() // copy the #firstrow
.removeAttr("id") // remove the duplicate ID
.append('<a class="remover" href="#">Remove</a>') // add a "remove" link
.insertAfter("#firstrow"); // add to the form
e.preventDefault();
});
$(".remover").live("click",function(e) {
// .live() acts on .removers that aren't created yet
$(this).parent().remove(); // remove the parent div
e.preventDefault();
});
});
</script>
HTML:
Add New Row
<form id="myform">
<div id="firstrow">
Name: <input type="text" name="name[]" size="5">
Year: <input type="text" name="year[]" size="4">
Description: <input type="text" name="desc[]" size="6">
</div>
<div>
<input type="submit">
</div>
</form>
Try enclosing them in a div element and then you can just remove the entire div.
Try this
Markup
<div class="inputFields">
..All the input fields here
</div>
Add
<div class="additionalFields">
</div>
JS
$("#add").click(function(){
var $clone = $(".inputFields").clone(true);
$clone.append($("<span>Remove</span").click(functio(){
$(this).closest(".inputFields").remove();
}));
$(".additionalFields").append($clone);
});
There are 2 plugins you may consider:
jQuery Repeater
jquery.repeatable
This question has been posted almost 4 years ago. I just provide the info in case someone needs it.