multiple functions in javascript fail when in one file - javascript

I have been working on a webpage with some simple form validation and submit using javascript functions and ajax. I have written a function that validates a form and then submits it to another php page. I have then created a second form and validating/submitting javascript function. Both work separately, so I don't think it is my functions that are wrong, however when I try to put them into one js file to call them, only one of the functions works. I can remove the other re-upload it and it calls fine. I would appreciate it if someone could spot what I am doing wrong.
$(function () {
$('.error').hide();
});
function publication(){
$('.error').hide();
var title = $("input#title").val();
if (title == "") {
$("label#title_error").show();
$("label#title_error").css("color", "red");
$("input#title").focus();
return false;
}
var author = $("input#author").val();
if (author == "") {
$("label#author_error").show();
$("label#author_error").css("color", "red");
$("input#author").focus();
return false;
}
var publisher = $("input#publisher").val();
if (publisher == "") {
$("label#publisher_error").show();
$("label#publisher_error").css("color", "red");
$("input#publisher").focus();
return false;
}
var avail = $("input#avail").val();
if (avail == "") {
$("label#avail_error").show();
$("label#avail_error").css("color", "red");
$("input#avail").focus();
return false;
}
var info = $("textarea#info").val();
if (info == "") {
$("label#info_error").show();
$("label#info_error").css("color", "red");
$("textarea#info").focus();
return false;
}
var webaddr = $("input#webaddr").val();
var YYYY = $("input#YYYY").val();
var img = $("input#img").val();
var dataString = 'title='+ title + '&author=' + author + '&publisher=' + publisher + '&avail=' + avail + '&info=' + info + '&YYYY=' + YYYY + '&webaddr=' + webaddr + '&img=' + img;
//alert (dataString);return false;
$.ajax({
type: "POST",
url: "/includes/add_publication.php",
data: dataString,
success: function() {
$('#event_form').html("<div id='message'></div>");
$('#message').html("<h2>Publication Added</h2>")
.append("<p>The publication has been added to the database.</p>")
.hide()
.fadeIn(1500);
}
});
return false;
}
function events(){
$('.error').hide();
var eventname = $("input#eventname").val();
if (eventname == "") {
$("label#event_error").show();
$("label#event_error").css("color", "red");
$("input#eventname").focus();
return false;
}
var venue = $("input#venue").val();
if (venue == "") {
$("label#venue_error").show();
$("label#venue_error").css("color", "red");
$("input#venue").focus();
return false;
}
var info = $("textarea#info").val();
if (info == "") {
$("label#info_error").show();
$("label#info_error").css("color", "red");
$("textarea#info").focus();
return false;
}
var webaddr = $("input#webaddr").val();
var DD = $("input#DD").val();
var MM = $("input#MM").val();
var YYYY = $("input#YYYY").val();
var DD2 = $("input#DD2").val();
var MM2 = $("input#MM2").val();
var YYYY2 = $("input#YYYY2").val();
var img = $("input#img").val();
var dataString = 'eventname='+ eventname + '&venue=' + venue + '&info=' + info + '&webaddr=' + webaddr + '&DD=' + DD + '&MM=' + MM + '&YYYY=' + YYYY + '&DD2=' + DD2 + '&MM2=' + MM2 + '&YYYY2=' + YYYY2 + '&img=' + img;
//alert (eventString);return false;
$.ajax({
type: "POST",
url: "/includes/add_event.php",
data: dataString,
success: function() {
$('#event_form').html("<div id='message'></div>");
$('#message').html("<h2>Event Added</h2>")
.append("<p>The event has been added to the database.</p>")
.hide()
.fadeIn(1500);
}
});
return false;
}
The publication and events functions are called via click handlers in the HTML (here it's publication):
<table width="100%" id="publication">
<tr>
<td width="20%">Title:</td>
<td>
<input name="title" type="text" id="title" size="50" />
</td>
<td width="30%">
<label class="error" for="title" id="title_error">This field is required.</label>
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td>Author:</td>
<td>
<input name="author" type="text" id="author" size="50" />
</td>
<td>
<label class="error" for="author" id="author_error">This field is required.</label>
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td>Publisher:</td>
<td>
<input name="publisher" type="text" id="publisher" size="50" />
</td>
<td>
<label class="error" for="publisher" id="publisher_error">This field is required.</label>
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td>Publication Year:</td>
<td>
<input name="YYYY" type="text" id="YYYY" size="4" />
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td>Website:</td>
<td>http://
<input name="webaddr" type="text" id="webaddr" size="50" />
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td>Availability:</td>
<td>
<input name="avail" type="text" id="avail" size="30" />
</td>
<td>
<label class="error" for="avail" id="avail_error">This field is required.</label>
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td valign="top">Publication Information:</td>
<td>
<textarea rows="4" cols="50" name="info" id="info"></textarea>
</td>
<td>
<label class="error" for="info" id="info_error">This field is required.</label>
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td>Image Name:</td>
<td>
<input name="img" type="text" id="img" size="50" />
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" name="submit" class="button" id="pubs_btn" value="Add" onclick="publication()" />
</td>
</tr>
</table>
As you can hopefully see there are three things happening here. 1: all error messages are being hidden on page load, second and third are my two functions - publication and events. I have several verified fields which get given a rec error message if they are blank. I am then sending all the variables into a string to be submitted via ajax to a php file to insert them into my sql database.
I could be missing something as simple as a semi-colon somewhere - but as I have never written multiple functions in one file I haven't worked that out.

You have a syntax error:
var eventString = 'eventname='+ eventname + '&venue=' + venue + '&info=' + info '&webaddr' + webaddr + '&DD' + DD + '&MM' + MM + '&YYYY' + YYYY + '&DD2' + DD2 + '&MM2' + MM2 + '&YYYY2' + YYYY2 + '&img' + img;
// Here ------------------------------------------------------------------------^
This prevents your JavaScript from being correctly parsed, thereby preventing your code from being run when the click occurs.
Your web browser was telling you about this: If you open your web console or developer tools, you'll see the error listed.

Related

My validation does not work on added rows and autonumbering

I have a function where i can add rows and autonumbering. The add rows works when you click the "add row" button, and auto numbering works when you press Ctrl+Enter key when there's 2 or more rows. My problem is, my validation does not work on my autonumbering.
For example: when I type manually the "1" on the textbox, it works.
But when I do my auto numbering, "Not good" does not appear on my 2nd
textbox.
Is there anything I missed? Any help will be appreciated.
//this is for adding rows
$("#addrow").on('click', function() {
let rowIndex = $('.auto_num').length + 1;
let rowIndexx = $('.auto_num').length + 1;
var newRow = '<tr><td><input class="auto_num" type="text" name="entryCount" value="' + rowIndexx + '" /></td>"' +
'<td><input name="lightBand' + rowIndex + '" value="" class="form" type="number" /> <span class="email_result"></span></td>"' +
'<td><input type="button" class="removerow" id="removerow' + rowIndex + '" name="removerow' + rowIndex + '" value="Remove"/></td>';
$("#applicanttable > tbody > tr:last").after(newRow);
});
//this is for my validation
$(document).on('change', 'input[name*=lightBand]', function() {
var lightBand1 = $(this).val(); //get value
var selector = $(this) //save slector
selector.next('.email_result').html("") //empty previous error
if (lightBand1 != '') {
/*$.ajax({
url: "<?php echo base_url(); ?>participant/check_number_avalibility",
method: "POST",
data: {
lightBand1: lightBand1
},
success: function(data) {*/
selector.next('.email_result').html("NOT GOOD"); //use next here ..
/* }
});*/
}
});
// this is for autonumbering when ctrl+enter is pressed.
const inputs = document.querySelectorAll(".form");
document.querySelectorAll(".form")[0].addEventListener("keyup", e => {
const inputs = document.querySelectorAll(".form");
let value = parseInt(e.target.value);
if ((e.ctrlKey || e.metaKey) && (e.keyCode == 13 || e.keyCode == 10)) {
inputs.forEach((inp, i) => {
if (i !== 0) {
inp.value = ++value;
}
})
}
});
Add a row and type any number at number textbox column and press ctrl+enter. You'll see the "Not good" is not working on added rows. It'll only work if you enter the number manually per row.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<table class="table table-bordered" border="1" id="applicanttable">
<thead>
<tr>
</tr>
</thead>
<tbody>
<div class="row">
<tr>
<th>#</th>
<th>Number</th>
<th>Action</th>
</tr>
<tr id="row_0">
<td>
<input id="#" name="#" class="auto_num" type="text" value="1" readonly />
</td>
<td class="labelcell">
<input value="" class="form" name="lightBand1" placeholder="" id="lightBand1" />
<span class="email_result"></span>
</td>
<td class="labelcell">
<input type="button" class="removerow" id="removerow0" name="removerow0" value="Remove">
</td>
</tr>
</div>
</tbody>
<tfoot>
<tr>
</tr>
<tr>
<button type="button" id="addrow" style="margin-bottom: 1%;">Add Row</button>
</tr>
</tfoot>
</table>
You can call your event handler i.e : change whenever you change your input values by auto numbering . So , use $(this).trigger("change") where this refer to input where value is changed .
Demo Code :
$("#addrow").on('click', function() {
let rowIndex = $('.auto_num').length + 1;
let rowIndexx = $('.auto_num').length + 1;
var newRow = '<tr><td><input class="auto_num" type="text" name="entryCount" value="' + rowIndexx + '" /></td>"' +
'<td><input name="lightBand' + rowIndex + '" value="" class="form" type="number" /> <span class="email_result"></span></td>"' +
'<td><input type="button" class="removerow" id="removerow' + rowIndex + '" name="removerow' + rowIndex + '" value="Remove"/></td>';
$("#applicanttable > tbody > tr:last").after(newRow);
});
//this is for my validation
$(document).on('change', 'input[name*=lightBand]', function() {
var lightBand1 = $(this).val(); //get value
var selector = $(this) //save slector
selector.next('.email_result').html("") //empty previous error
if (lightBand1 != '') {
/*$.ajax({
url: "<?php echo base_url(); ?>participant/check_number_avalibility",
method: "POST",
data: {
lightBand1: lightBand1
},
success: function(data) {*/
selector.next('.email_result').html("NOT GOOD"); //use next here ..
/* }
});*/
}
});
// this is for autonumbering when ctrl+enter is pressed.
$(document).on('keyup', '.form', function(e) {
let value = parseInt(e.target.value);
if ((e.ctrlKey || e.metaKey) && (e.keyCode == 13 || e.keyCode == 10)) {
//loop through all values...
$(".form").each(function(i) {
if (i !== 0) {
$(this).val(++value); //assign new value..
$(this).trigger("change") //call your change event to handle further...
}
})
}
})
Add a row and type any number at number textbox column and press ctrl+enter. You'll see the "Not good" is not working on added rows. It'll only work if you enter the number manually per row.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<table class="table table-bordered" border="1" id="applicanttable">
<thead>
<tr>
</tr>
</thead>
<tbody>
<div class="row">
<tr>
<th>#</th>
<th>Number</th>
<th>Action</th>
</tr>
<tr id="row_0">
<td>
<input id="#" name="#" class="auto_num" type="text" value="1" readonly />
</td>
<td class="labelcell">
<input value="" class="form" name="lightBand1" placeholder="" id="lightBand1" />
<span class="email_result"></span>
</td>
<td class="labelcell">
<input type="button" class="removerow" id="removerow0" name="removerow0" value="Remove">
</td>
</tr>
</div>
</tbody>
<tfoot>
<tr>
</tr>
<tr>
<button type="button" id="addrow" style="margin-bottom: 1%;">Add Row</button>
</tr>
</tfoot>
</table>

onsubmit event not working in IE11

I have a form that uses the onsubmit event.
Tested in MS Blade, Chrome Version 67, Firefox Version 60 and the event works as expected.
This means a dialogue box appears and asks "do you wish to proceed with the order and lists the item and value". With options to select "ok" or "cancel".
Tested in IE11 and the event fires but goes directly to the cancel option and reloads the page.
<form onsubmit="confirmBox()" action="#" name="order_form" id="order_form">
<table>
<tr>
<td>Price</td>
<td><div id="divPriceObj"></div></td>
<td><input type="hidden" name="price" id="price" value=""></td>
</tr>
<tr>
<td><label>Quantity</label></td>
<td><input type="number" name="quantity" id="quantity" min="1" value="1"></td>
<td>REQUIRED FIELD</td>
<td><input type="hidden" name="description" id="description" value=""></td>
</tr>
<tr>
<td><label>Total Price</label></td>
<td><div id="totalPrice"></div></td>
</tr>
<tr>
<td><button type="button" onclick="resetQuantity()">Clear</button></td>
<td><button type="button" onclick="calculateTotal()">Calculate Total</button></td>
<td><input type="submit" name="submit" id="submit" value="Submit" /></td>
</tr>
</table>
</form>
The Javascript involved is
function confirmBox() {
var itemDesc = setDesc(getUrlVars()["description"]);
var itemPrice = document.forms["order_form"]["price"].value;
var itemQuantity = document.forms["order_form"]["quantity"].value;
var itemTotal = itemPrice * itemQuantity;
//check if form data is valid still
if (validateForm(price, quantity)) {
var x = document.forms["order_form"]["price"].value;
var y = document.forms["order_form"]["quantity"].value;
var z = getUrlVars()["desc"];
if (confirm('Do you wish to Proceed with the order of '
+ itemQuantity
+ ' ' + itemDesc
+ ' valued at $'
+ itemTotal + '?')) {
close();
} else {
resetQuantity();
}
} else {
//do nothing
//close();
}
}
I have not been able to fix this bug, does anyone have a solution?

When tabout event get fire i want to add new row under current row .But combo box does not load?

Html code:
Below image describes my output.Please kindly some one help me to resolve this issue.
<table class="table table-striped table-bordered table-hover table-condensed tableSiteUser">
<thead>
<tr>
<th>#</th>
<th>SiteName</th>
<th>UserName</th>
<th>Channel</th>
<th>Action</th>
</tr>
</thead>
<tbody id="site-table-body">
<tr>
<td class="countsiteuser">1</td>
<td><select class="form-control" id="siteContainer"></select>
</td>
<td><input type="checkbox" value="user" id="checkboxbutton"><input type="text" class="and" disabled placeholder="Default"/></td>
<td><input type="text" class="form-control" placeholder="Enter the Channel"/></td>
<td><span class="form-control glyphicon glyphicon-trash"></span></td>
</tr>
</tbody>
</table>
JavaScript:
$('.tableSiteUser').on('keydown','td:nth-child(4)',function(e){
var keyCode=e.keyCode || e.which;
if(keyCode == 9){
serialUserSite++;
$('tbody#site-table-body').append('<tr>'
+'<td class="beer" contenteditable="false">'+serialUserSite+'</td>'
+'<td><select class="form-control" id="siteContainer">'
+'</select></td>'
+'<td><input type="checkbox" value="user" id="checkboxbutton"><input type="text" class="and" disabled placeholder="Default"/></td>'
+'<td><input type="text" class="form-control" placeholder="Enter the Channel"/></td>'
+'<td><span class="glyphicon glyphicon-trash form-control"></span></td>'
+'</tr>');
}
});
ajax code:
$.ajax({
url : "http://localhost:8080/IDNS_Rule_Configuration/idns/systemData/getAllSites",
type : "GET",
contactType : "application/json",
dataType : "json",
success : function(data){
for(var i=0;i<data.length;i++){
var dataId = data[i].siteId;
var dataArray = data[i].siteName;
$('#siteContainer').populate(dataId, dataArray);
}
}
});
populate jquery code:
$.fn.populate = function(dataId, dataArray) {
var $selectbox = $(this);
// check if eleme nt is of type select
if ($selectbox.is("select")) {
//for (var i = 0; i < dataId.length; i++) {
$selectbox.append('<option value="' + dataId
+ '" stream="' + dataId + '">'
+ dataArray + '</option>');
//}
}
};
This is my output ,site name combo box is loaded from db.In first row it works .At second row it does not work

AJAX: add new row to table or remove using AJAX

This is the logic:
I input something to form, and the form is AJAX live search. after I found value, I click on add button and it creates new row in existing table / tbody.
<table class="standard">
<thead>
<tr>
<td colspan="2">
Start Input barcode / Product Name
</td>
<td colspan="4">
<input type="text" size="90" value="" placeholder="Barcode / Product Name">
</td>
<td>
<button class="tambah"><i class="icon-plus"></i> Add</button>
</td>
</tr>
<tr>
<td>
No.
</td>
<td>
Kode Barang
</td>
<td>
Nama Barang
</td>
<td>
Qty
</td>
<td>
Harga
</td>
<td>
Disc %
</td>
<td>
Total
</td>
</tr>
</thead>
<tbody>
<!-- when button add is click that will add <tr></tr> here -->
</tbody>
</table>
can i do that? if so, how?
Fiddle Example: http://jsfiddle.net/anggagewor/cauPH/
You can find the pseudo code below.
$('#button_id').on('click', function(e) {
$.ajax({
url : yourUrl,
type : 'GET',
dataType : 'json',
success : function(data) {
$('#table_id tbody').append("<tr><td>" + data.column1 + "</td><td>" + data.column2 + "</td><td>" + data.column3 + "</td></tr>");
},
error : function() {
console.log('error');
}
});
});
Try this
var scntDiv = $('#p_scents');
var i = $('#p_scents tr').size() + 1;
$('#addScnt').click(function() {
scntDiv.append('<tr><td><select name="type" id="type"><option value="Debit">Debit</option><option value="Credit">Credit</option></select></td><td><select name="accounts" id="accounts"><option value="">SELECT</option><option value="One">One</option><option value="Two">Two</option></select></td><td><input type="text" name="debit_amount" id="debit_amount"/></td><td><input type="text" name="credit_amount" id="credit_amount"/></td><td>Remove</td></tr>');
i++;
return false;
});
//Remove button
$(document).on('click', '#remScnt', function() {
if (i > 2) {
$(this).closest('tr').remove();
i--;
}
return false;
});​
Here's a working example, including remove row functionality: DEMO.
$("<tr><td>.....content...<td><a class='remove'>remove</a>").appendTo("#tableid tbody").find('.remove').click(function () {
$(this).parent().parent().remove();
});
In your ajax response you can do this
$("#myTable > tbody").append('<tr><td>my data</td><td>more data</td></tr>');
'#myTable' will be replaced by your table id or class and <td>my data</td><td>more data</td> will be replaced by your content

JavaScript checking & adding text to a table dynamically on submit button click

Basically my HTML looks like this:
<form method="post" name="htmlform" onsubmit = "checkFields()">
<table style="width: 479px;" border="30" cellspacing="3" cellpadding="10">
<tbody>
<tr>
<td valign="top"><span id="firstNameSpan" >First Name *</span></td>
<td valign="top"><input type="text" name="first_name" id="first_name"
size="30" maxlength="50" /></td>
</tr>
<tr>
<td valign="top"><span id = "lastNameSpan" >Last Name *</span></td>
<td valign="top"><input type="text" name="last_name" size="30" maxlength="50"/>
/td>
</tr>
<tr>
<td style="text-align: center;" colspan="2"><input type="radio" name="sex"
value="male" /> Male <input type="radio" name="sex"
value="female" /> Female</td>
</tr>
<tr>
<td style="text-align: center;" colspan="2"><input type="submit" value="submit"
/></td>
</tr>
</tbody>
</table>
</form>
When the form is submitted, the onsubmit() event checks if first_name textfield is blank, if it is then the label or span to its left is appended to output "first name*" + " you must enter a first name" and similarly for last name and sex.
The problem is that the text in the table does not update with appendchild. When I enclosed the statement in an alert for debugging the message is appended then disappears.
The JavaScript code is below for the onsubmit = "checkFields()".
function checkFields() {
var firstName = document.getElementById("first_name").value;
var lastName = document.getElementById("last_name").value;
if (firstName == "") {
//<span style='color:red'> Please enter a first name </span>
var nameHint = " Please enter a first name";
var node = document.getElementById("firstNameSpan");
//alert(node.appendChild(document.createTextNode(nameHint)) );
//not working
node.appendChild(document.createTextNode(nameHint));
} if (lastName == "") {
//additional code
}
}
Thanks in advance, your help is much appreciated. Also are there any JavaScript debuggers?
Regards
David D
I believe your sample code is not working due to incorrect html. document.getElementById("last_name") will return undefined.
http://jsfiddle.net/5E6my/1/
Thanks all, Im getting the ropes of JFiddle the split screen is very useful although the error messages are not useful for debugging. Here is the completed code (1) HTML (2) JavaScript.
<form method="post" name="htmlform" onsubmit="return checkFields();">
<table style="width: 479px;" border="30" cellspacing="3" cellpadding="10">
<tbody>
<tr>
<td valign="top"><span id="firstNameSpan" >First Name *</span></td>
<td valign="top"><input type="text" name="first_name" id="first_name"
size="30" maxlength="50" /></td>
</tr>
<tr>
<td valign="top"><span id = "lastNameSpan" >Last Name *</span></td>
<td valign="top"><input type="text" name="last_name" id="last_name" size="30"
maxlength="50" /></td>
</tr>
<tr>
<td style="text-align: center;" colspan="2" id = "sexMessage">
Please select Male or Female*</td>
</tr>
<tr>
<td style="text-align: center;" colspan="2"><input type="radio"
name="sex" value="male" /> Male <input type="radio" name="sex"
value="female" /> Female</td>
</tr>
<tr>
<td style="text-align: center;" colspan="2"><input type="submit" value="submit"
/></td>
</tr>
</tbody>
</table>
</form>
The JavaScript code to react to the onsubmit button's unfilled fields in the form are: (any ways to make this code simpler??)
window.checkFields = function()
{
var firstName = document.getElementById("first_name");
var lastName = document.getElementById("last_name");
if(firstName.value == "")
{
//<span style='color:red'> Please enter a first name </span>
var nameHint = " *Please enter a first name ";
var fnNode = document.getElementById("firstNameSpan");
while(fnNode.firstChild)
{
fnNode.removeChild(fnNode.firstChild)
}
fnNode.appendChild(document.createTextNode(nameHint));
fnNode.style.color="red";
} else{
var nameHint = " First Name *";
var fnNode = document.getElementById("firstNameSpan");
while(fnNode.firstChild)
{
fnNode.removeChild(fnNode.firstChild)
}
fnNode.appendChild(document.createTextNode(nameHint));
fnNode.style.color="black";
}
if (lastName.value == "")
{
//additional code
var nameHint = " *Please enter a last name";
var lnNode = document.getElementById("lastNameSpan");
while(lnNode.firstChild)
{
lnNode.removeChild(lnNode.firstChild)
}
lnNode.appendChild(document.createTextNode(nameHint));
lnNode.style.color="red";
} else{
var nameHint = " Last Name *";
var lnNode = document.getElementById("lastNameSpan");
while(lnNode.firstChild)
{
lnNode.removeChild(lnNode.firstChild)
}
lnNode.appendChild(document.createTextNode(nameHint));
lnNode.style.color="black";
}
var radios = document.getElementsByName("sex");
var radioValue = ""
for(var i=0; i<radios.length; i++)
{
if(radios[i].checked)
{
radioValue = radios[i].value;
}
}
if(radioValue === "")
{
var sexNode = document.getElementById("sexMessage");
var nameHint = "*You did not choose a sex";
while(sexNode.firstChild)
{
sexNode.removeChild(sexNode.firstChild);
}
sexNode.appendChild(document.createTextNode(nameHint));
sexNode.style.color="red";
} else {
var sexNode = document.getElementById("sexMessage");
var nameHint = "Please select Male or Female*";
while(sexNode.firstChild)
{
sexNode.removeChild(sexNode.firstChild);
}
sexNode.appendChild(document.createTextNode(nameHint));
sexNode.style.color="black";
}
return false;
}
The trick is to use as Yury suggested was the onsubmit="return checkfields()" and then in the code block to use window.checkFields = function() { etc.
One question that I have... is JQuery a lot simpler to use, im learning JavaScript before JQuery... should I skip to JQUery instead. Also does JQuery support the AJAX framework?
Much appreciated
David

Categories

Resources