I have a dialog that contains inputs,
User should complete dialog inputs then click send,
After that, user can open the same dialog again and complete dialog inputs.
But when the user open the dialog again, input values remain as same from previous inputs,
How can I remove previous input values?
My Dialog:
<dialog id="main-customers">
<h2>العملاء الرئيسيون</h2>
<div>
<label for="main-customers-name">الاسم</label>
<input type="text" id="main-customers-name" placeholder="الاسم" required>
<label for="main-customers-country">الدولة</label>
<input type="text" id="main-customers-country" placeholder="الدولة" required>
<label for="main-customers-goods">سلع / بضائع</label>
<input type="text" id="main-customers-goods" placeholder="سلع / بضائع" required>
</div>
<div class="center">
<button id="main-customers-send">إرسال</button>
<button id="main-customers-cancel" onclick="closeDialog('main-customers')">إلغاء</button>
</div>
</dialog>
My JS:
document.getElementById("main-customers-send").addEventListener("click", function(){
// to remove initial value
var no_data= document.getElementById("main-customers-table-no-data");
if(no_data){
no_data.remove()
}
// END to remove initial value
var name= document.getElementById("main-customers-name");
var country= document.getElementById("main-customers-country");
var goods= document.getElementById("main-customers-goods");
document.getElementById("main-customers-table").innerHTML+=
`<tr>
<td>${name.value}</td>
<td>${country.value}</td>
<td>${goods.value}</td>
</tr>`;
let itms = document.querySelectorAll("#main-customers");
for (let itm of itms) {
if(itm.value != ""){
itm.value= ""; //it does not do the job
}
}
closeDialog("main-customers")
})
-
values remain the same as shown below:
The line let itms = document.querySelectorAll("#main-customers"); doesn't do what you think it does. It selects all the elements with the id "main-customers" (which per spec a page could only have one of).
Try let itms = document.querySelectorAll("#main-customers input[type=text]"); instead of that which will select all the children of the #main-customers element that is an input whose type is text.
Related
I'm building a multipage form. On a few of the form's pages, I have questions that allow the user to add inputs dynamically if they need to add a job, or an award, etcetera. Here's what I'd like to do/what I have done so far.
What I Want to Do:
As the user adds fields dynamically, I want to validate those fields to make sure they have been filled in, and they are not just trying to move to the next page of the form with empty inputs.
After all the fields are successfully validated, a "Next" button at the bottom of the page, which up until this point was disabled, will become reenabled.
What I know How To Do
With some help, I've been able to workout a validation pattern for the inputs that are not dynamically added (such as First Name, Last Name) and I can extend this same logic to the first set of inputs that are not added dynamically. I have also worked out how to re-enable the "Next" button once all fields are good.
What I do Not Know How To Do
How do I write a function that extends the logic of the simple validation test to also check for dynamically added iterations.
http://codepen.io/theodore_steiner/pen/gwKAQX
var i = 0;
function addJob()
{
//if(i <= 1)
//{
i++;
var div = document.createElement("div");
div.innerHTML = '<input type="text" class="three-lines" placeholder="School Board" name="schoolBoard_'+i+'"> <input type="text" class="three-lines" placeholder="Position" name="position_'+i+'"> <input type="date" class="three-lines" name="years_'+i+'"> <input type="button" value="-" onclick="removeJob(this)">';
document.getElementById("employmentHistory").appendChild(div);
//}
}
function removeJob(div)
{
document.getElementById("employmentHistory").removeChild(div.parentNode);
i--;
};
function checkPage2()
{
var schoolBoard_1 = document.getElementById("schoolBoard_1").value;
if(!schoolBoard_1.match(/^[a-zA-Z]*$/))
{
console.log("something is wrong");
}
else
{
console.log("Working");
}
};
<div id="page2-content">
<div class="input-group" id="previousTeachingExperience">
<p class="subtitleDirection">Please list in chronological order, beginning with your most recent, any and all full-time or part-time teaching positions you have held.</p>
<div class="clearFix"></div>
<label id="teachingExpierience">Teaching Experience *</label>
<div id="employmentHistory">
<input type="text" class="three-lines" name="schoolBoard_1" id="schoolBoard_1" placeholder="School Board" onblur="this.placeholder='School Board'" onfocus="this.placeholder=''" onkeyup="checkPage2()" />
<input type="text" class="three-lines" name="position_1" placeholder="Position" onblur="this.placeholder='Position'" onfocus="this.placeholder=''" onkeyup="checkPage2()" />
<input type="date" class="three-lines" name="years_1" />
<input type="button" name="myButton" onclick="addJob()" value="+" />
</div>
</div><!--end of previousTeachingExperience Div -->
Instead of trying to validate each individual input element, I would recommend trying to validate them all at once. I believe that is what your checkPage2 function is doing.
You can add the onBlur event handler or the onKeyUp event handler you are currently using to all added inputs to run your form wide validation. This has the effect of checking each individual form element if it is valid so you know for sure you can enable the submit button.
Lastly, when removeJob is called, you should also run the form wide validation. It would look something like this:
function addJob()
{
i++;
var div = document.createElement("div");
div.innerHTML = '<input type="text" class="three-lines" placeholder="School Board" name="schoolBoard_'+i+'" onkeyup="checkPage2()"> <input type="text" class="three-lines" placeholder="Position" name="position_'+i+'" onkeyup="checkPage2()"> <input type="date" class="three-lines" name="years_'+i+'" onkeyup="checkPage2()"> <input type="button" value="-" onclick="removeJob(this)">';
document.getElementById("employmentHistory").appendChild(div);
}
function removeJob(div)
{
document.getElementById("employmentHistory").removeChild(div.parentNode);
i--;
checkPage2();
};
For every element that you make with document.createElement(...), you can bind to the onchange event of the input element, and then perform your validation.
Here's an updated version of your CodePen.
For example:
HTML
<div id="container">
</div>
Javascript
var container = document.getElementById("container");
var inputElement = document.createElement("input");
inputElement.type = "text";
inputElement.onchange = function(e){
console.log("Do validation!");
};
container.appendChild(inputElement);
In this case I'm directly creating the input element so I have access to its onchange property, but you can easily also create a wrapping div and append the inputElement to that.
Note: Depending on the freqency in which you want the validation to fire, you could bind to the keyup event instead, which fires every time the user releases a key while typing in the box, IE:
inputElement.addEventListener("keyup", function(e){
console.log("Do validation!");
});
I am programming a web application which accepts barcodes from a barcode reader in an input field. The user can enter as many barcodes that s/he wants to (i.e. there is no reason for a predefined limit). I have come up with a brute force method which creates a predefined number of hidden input fields and then reveals the next one in sequence as each barcode is entered. Here is the code to do this:
<form id="barcode1" name="barcode" method="Post" action="#">
<div class="container">
<label for="S1">Barcode 1   </label>
<input id="S1" class="bcode" type="text" name="S1" onchange="packFunction()" autofocus/>
<label for="S2" hidden = "hidden">Barcode 2   </label>
<input id="S2" class="bcode" type="text" hidden = "hidden" name="S2" onchange="packFunction()" />
<label for="S3" hidden = "hidden">Barcode 3   </label>
<input id="S3" class="bcode" type="text" hidden = "hidden" name="S3" onchange="packFunction()" />
<label for="S4" hidden = "hidden">Barcode 4   </label>
<input id="S4" class="bcode" type="text" hidden = "hidden" name="S4" onchange="packFunction()" />
<label for="S5" hidden = "hidden">Barcode 5   </label>
<input id="S5" class="bcode" type="text" hidden = "hidden" name="S5" onchange="packFunction()" />
</div>
<div class="submit">
<p><input type="submit" name="Submit" value="Submit"></p>
</div>
</form>
<script>
$(function() {
$('#barcode1').find('.bcode').keypress(function(e){
// to prevent 'enter' from submitting the form
if ( e.which == 13 )
{
$(this).next('label').removeAttr('hidden')
$(this).next('label').next('.bcode').removeAttr('hidden').focus();
return false;
}
});
});
</script>
This seems to be an inelegant solution. It would seem to be better to create a new input field after each barcode has been entered. I have tried creating new input elements in the DOM using jQuery, and I can get the new input element to show. But it uses the onchange event, which detects changes in the original input field. How do I transfer focus and detect onchange in the newly created input field? Here is the code that I have played with to test out the idea:
<div>
<input type="text" id="barcode" class="original"/>
</div>
<div id="display">
<div>Placeholder text</div>
</div>
<script src="./Scripts/jquery-2.2.0.min.js"></script>
$(function () {
$('#barcode').on('change', function () {
$('#display').append('<input id='bcode' class='bcode' type='text' name='S1' autofocus/>')
});
});
</script>
Once I have these barcodes, I pack them into array which I then post them to a server-side script to run a mySQL query to retrieve data based on the barcodes, and then post that back to the client. So part of what I have to achieve is that each barcode that is entered into the different input fields need to be pushed into an array.
Is there an elegant way to accomplish the creation of input fields dynamically and then detecting changes in those to create yet more input fields?
The dynamic update you have tried out is all right. If you must push it into an array on submit you have to prevent default of form submit, serialize the form and then make an ajax request.
Heres an example:
$('form').on('submit',function(e){
e.preventDefault();
var formData = $(this).serializeArray();//check documentation https://api.jquery.com/serializeArray/ for more details
$.ajax({
type:'post',
url:<your url>//or you could do $('form').attr('action')
data:formData,
success:function(){}//etc
})
});
If you do not display the barcodes in the html you can skip the input fields and store the read barcodes in an array[]. Not everything that happens in javascript has to be displayed in the website (View) . i do not know what code you use to scan the barcode but you do not need the input-elements at all.
See the example on this site https://coderwall.com/p/s0i_xg/using-barcode-scanner-with-jquery
instead of console.log() the data from the barcode scanner can simply be saved in an array[] and be send from there.
If you want to create elements dynamcially see this thread: dynamically create element using jquery
The following code adds the p-element with the label "Hej" to the div "#contentl1"
`$("<p />", { text: "Hej" }).appendTo("#contentl1");`
UPDATE: I added some simple CSS to make each input field display on its own line.
Here's one strategy:
Listen for the enter/return key on the input box.
When the enter/return key is pressed (presumably after entering a barcode), create a new input box.
Stop listening for the enter key on the original input and start listening for it on the new input.
When a "submit all" button is pressed (or when tab is used to shift the focus from the most recent input to the "submit all" button and enter is pressed), then collect all the input values in an array.
$(function() {
var finishBarcode = function(evt) {
if (evt.which === 13) {
$(evt.target).off("keyup");
$("<input class='barcode' type='text'/>")
.appendTo("#barcodes")
.focus()
.on("keyup", finishBarcode);
}
};
var submitBarcodes = function(evt) {
var barcodesArr = $(".barcode").map(function() {
return $(this).val();
}).get();
$("#display").text("Entered Barcodes: " + barcodesArr);
};
var $focusedInput = $('.barcode').on("keyup", finishBarcode).focus();
var $button = $('#submitAll').on("click", submitBarcodes);
});
input.barcode {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Type barcode into input box</li>
<li>To enter barcode and allow new entry, press Return</li>
<li>To submit all barcodes, either press tab and then return or click Submit button</li>
</ul>
<div id="barcodes"><input type="text" class="barcode" /></div>
<div><button id="submitAll">Submit all barcodes</button></div>
<div id="display">Placeholder text</div>
I'm trying to create an HTML form which takes the text from multiple textboxes (in this case, 3) and adds the content of each to a list in a separate div, as well as create a new object "employee", all via the click of a button. My goal is to imitate adding employees to a database, using an employee id, first name, and last name as variables. I am looking to accomplish this using pure javascript.
What I have so far is:
<form>
ID Number:
<br>
<input type="text" id="idNumber">
<br>First name:
<br>
<input type="text" id="firstName">
<br>Last name:
<br>
<input type="text" id="lastName">
</form>
<br>
<button type="submit" onclick="myFunction(list)">Submit</button>
<div id="container">
<ul id="list"></ul>
</div>
In a separate JavaScript file:
function myFunction(list){
var text = document.getElementById("idNumber","fName","lName").value;
var li = "<li>" + text + "</li>";
document.getElementById("list").replaceChild(li);
}
When I debug my code it seems to be setting the values fine, but I receive no actual output of my list.
None of the input elements you selected had a class name. You can also do this with document.getElementById. Just add ids to all your form elements.
Your code should look something like this.
function myFunction(list){
var text = "";
var inputs = document.querySelectorAll("input[type=text]");
for (var i = 0; i < inputs.length; i++) {
text += inputs[i].value;
}
var li = document.createElement("li");
var node = document.createTextNode(text);
li.appendChild(node);
document.getElementById("list").appendChild(li);
}
http://jsfiddle.net/nb5h4o7o/3/
Your list wasn't being appended to because you weren't actually creating the elements. replaceChild should have been appendChild and you should have created a list element with document.createElement.
Your code is full of problems, look at the document.getElementById and Node.replaceChild docs.
I've created a version for you that we get all the input elements of your form (using querySelectorAll), and then we use Array.prototype.map to turn them into "<li>[value]</li>", and then Array.prototype.join to turn that array into a single string.
Then, we get that string and set the #list.innerHTML property.
document.querySelector('button').addEventListener('click', function(e) {
var form = document.querySelector('form'),
list = document.getElementById('list');
list.innerHTML = [].map.call(form.querySelectorAll('input'), function(el) {
return '<li>' + el.value + '</li>';
}).join('');
});
<form>
ID Number:
<br>
<input type="text" id="idNumber">
<br>First name:
<br>
<input type="text" id="firstName">
<br>Last name:
<br>
<input type="text" id="lastName">
</form>
<br>
<button type="submit">Submit</button>
<div id="container">
<ul id="list"></ul>
</div>
The following code produces a prompt with a single input box, however i need to have two input boxes . Is this achievable ?
alertify.prompt("Please enter Values","Default Text").set('onok', function(closeevent, value) {
if (value == "" || value == " " )
{
alertify.error("No value entered");
return;
}
else
{
updateItem(selectedItem,value);
}
}).set('title',"Update Values");
So i was able to achieve this with the following code :
<!-- the content to be viewed as dialog
***Define the two input boxes
*** Note the input element class "ajs-input" that i have used here , this is the class used by AlertifyJS for its Input elements.
-->
<div style="display:none;" >
<div id="dlgContent">
<p> Enter Value One </p>
<input class="ajs-input" id="inpOne" type="text" value="Input One Default Value"/>
<p> Enter Value Two </p>
<input class="ajs-input" id="inpTwo" type="text" value="Input two default Value"/>
</div>
</div>
<!-- the script -->
<script>
var dlgContentHTML = $('#dlgContent').html();
$('#dlgContent').html("");
/* This is important : strip the HTML of dlgContent to ensure no conflict of IDs for input boxes arrises" */
/* Now instead of making a prompt Dialog , use a Confirm Dialog */
alertify.confirm(dlgContentHTML).set('onok', function(closeevent, value) {
var inpOneVal = $('#inpOne').val();
var inpTwoVal = $('#inpTwo').val();
/* Insert your code to work with the two values */
}).set('title',"Update");
</script>
I am creating a set of textboxes dynamically while pressing (+) button, by cloning the following HTML template:
<div id= "other_leaders" class="controls form-input">
<input type="text" name="other_leader_fname[]" class="input_bottom other_leader_fname" id="other_leader_fname" placeholder="First Name" value="'.$val[0].'" />
<input type="text" name="other_leader_lname[]" class="input_bottom other_leader_lname" id="other_leader_lname" placeholder="Last Name" value="'.$val[1].'" />
<input type="text" name="other_leader_email[]" class="other_leader_email" id="other_leader_email" placeholder="Email Address" value="'.$val[2].'" />
<input type="text" name="other_leader_org[]" class="other_leader_org" id="other_leader_org" placeholder="Organisation/College" value="'.$val[3].'" />
<span class="remove btn"><i class="icon-minus"></i></span>
</div>
I am able to do single textbox validation by following code:
$("input[name*='other_leader_fname']").each(function(){
if($(this).val()=="" || !RegExpression.test($(this).val()))
{
$(this).addClass('custom-error')
fnameflag = 0;
}
});
Now my question is how to do empty validation for all four textboxes, if any one textbox field is filled by the user in that particular textbox group.
for example: if i enter values in the <div> with id other_leader_fname, then it should perform empty validation for other three textboxes of this particular group.
how can i do it?
Try this , You can apply your validation rules to all the text box in the div by using following code:
$("#other_leaders :input[type='text']").each(function(){
if($(this).val()=="" || !RegExpression.test($(this).val()))
{
$(this).addClass('custom-error')
fnameflag = 0;
}
});
As you have just one element so there is no need to have a loop over it:
var $othLeader = $("input[name*='other_leader_fname']");
if($othLeader.val()=="" || !RegExpression.test($othLeader.val())){
$(this).addClass('custom-error');
fnameflag = 0;
}
And if you have form then you can validate this in your form's submit function.
You can iterate over the .controls using the each() and check for filled inputs in each group using filter for performing the validation as follows:
$('.controls').each(function(){
var $inputs = $(this).find('input');
var filled = $inputs.filter(function(){
return this.value != "";
});
if(filled.length){
$inputs.each(function(){
if($(this).val()=="" || !RegExpression.test($(this).val()))
{
$(this).addClass('custom-error')
fnameflag = 0;
}
})
}
});
Demo
side note: since the above is a template for dynamically generated content, You should remove the id and use class instead since id should be unique in a document.