I created a form dynamically with javascript. Now I have to add validations on the form (only mandatory validations) on click of the button which is also dynamically created. Now the issue I am facing is that whenever I try to add addEventListener on the button exactly after creating it, it is giving me error.
(
function init() {
console.log("div created");
// create a new div element
var newDiv = document.createElement("div");
newDiv.id = "registration_form";
var createForm = document.createElement("form");
newDiv.appendChild(createForm);
var heading = document.createElement("h2");
heading.innerHTML = "Registration Form";
createForm.appendChild(heading);
var linebreak = document.createElement('br');
createForm.appendChild(linebreak);
createElement(createForm, 'label','','','Name: ');
createElement(createForm, 'text', 'dname', '','');
createSpanTag(createForm,'nameError');
breakTag(createForm);breakTag(createForm);
createElement(createForm, 'label','','','Email: ');
createElement(createForm, 'email', 'email', '','');
createSpanTag(createForm,'emailError');
createElement(createForm, 'button','Validate','Validate','');
document.getElementsByTagName('button')[0].addEventListener('click',validate());
document.getElementsByTagName('body')[0].appendChild(newDiv);
}
)();
function createElement(formElement,type,name,value, placeholder) {
if(type=='label'){
var element=document.createElement(type);
if(name!='' && value!=''){
element.setAttribute('name',name);
element.setAttribute('value',value);
}
element.innerHTML=placeholder;
formElement.appendChild(element);
} else {
var element=document.createElement('input');
if(type!=''){
element.setAttribute('type',type);
}
if(name!=''){
element.setAttribute('name',name);
}
if(value!=''){
element.setAttribute('value',value);
}
if(placeholder!=''){
element.setAttribute('placeholder',placeholder);
}
formElement.appendChild(element);
}
}
function breakTag(createForm){
createForm.appendChild(document.createElement('br'));
}
function validate(){
}
function createSpanTag(createForm, id){
var element=document.createElement('span');
element.setAttribute('id',id);
createForm.appendChild(element);
}
The second argument of addEventListener needs to be a function.
Change ...
document.getElementsByTagName('button')[0].addEventListener('click',validate())
to ...
document.getElementsByTagName('button')[0].addEventListener('click',validate);
Since your tag name is input, not button. So use input in parameter of the function getElementsByTagName() and then loop through all nodes and find node with type = button.
Try change this line:
document.getElementsByTagName('button')[0].addEventListener('click',validate());
to:
var nodeList = document.getElementsByTagName("input");
for (var i = 0; i < nodeList.length; i++)
{
if (nodeList[i].getAttribute("type") == "button") {
{
nodeList[i].addEventListener('click',validate);
}
}
Related
I have a group of dynamically generated input fields. I want to loop through all of them and check if the user has indeed written something on them. If all fields have been filled, activate the button, otherwise, desactivate it. Code is really long, so here is the most important part :
//Here is the loop that creates the number of inputs to create based on what the user enters:
(CourseObject.course_array).forEach((evaluation,value) => {
const percentage_value = CourseObject.each_evaluation_value[value];
//Some lists
const li_inputs = document.createElement('li');
li_inputs.id = ((`${evaluation}-of-${CourseName}-input-li`.replace(/°/g, "")).replace(/ /g, "")).toLocaleLowerCase();
li_inputs.className = "list-group-item";
(document.getElementById(`${CourseName}-input-ul`).appendChild(li_inputs));
//Here starts the important stuff, creation of the inputs and attributes
const text_input = document.createElement('input');
text_input.type = 'text';
text_input.placeholder = `Nota de ${evaluation} (${percentage_value}%)`;
text_input.id = ((`${evaluation}-of-${CourseName}-input-text`.replace(/°/g, "")).replace(/ /g, "")).toLocaleLowerCase();
text_input.className = 'form-control grade-input';
(document.getElementById(((`${evaluation}-of-${CourseName}-input-li`.replace(/°/g, "")).replace(/ /g, "")).toLocaleLowerCase())).appendChild(text_input);
}
);
//Creating the button
const SendAndShow = document.createElement('button');
SendAndShow.textContent = 'Calcular';
SendAndShow.id = 'send-and-show-button';
SendAndShow.disabled = true; //Desactivated from the beggining
SendAndShow.className = 'btn btn-dark';
document.getElementById('second-column').appendChild(SendAndShow);
//Here I want to loop through the inputs. If they are all filled, SendAndShow.disabled = false
//A random event set to be activated once the button is clicked
document.getElementById('send-and-show-button').onclick = function() {
.
. //Something to do
.
}
I have tried querySelectorAll and getting the element by class but I can't seem to be able to hack it, any suggestions?
Note : I would like a pure JS answer, no JQuery.
You can use the onchange method in every input element, then check the values of inputs with FormData
const form = document.querySelector('#form')
function getFormData() {
formData = new FormData(form)
console.log(formData.entries())
}
text_input.onchange = function(){
getFormData()
}
<form id='form'></form>
for dynamic element add listener to the parent or body then check your input elements
createInput.addEventListener('click', function() {
let input = document.createElement('input')
myform.prepend(input)
submit.setAttribute('disabled', '')
})
// the parent
myform.addEventListener('input', function(el) {
if (el.target.tagName != 'INPUT') return;
// chack all input
let allFilled = true
document.querySelectorAll('#myform input').forEach(function(input) {
if (!input.value)
allFilled = false;
})
// set the button state
if (allFilled)
submit.removeAttribute('disabled')
else
submit.setAttribute('disabled', '')
})
input{display:block;margin:10px;}
<button id="createInput">Create input</button><br><br>
<form id="myform">
<button id="submit" disabled>Submit</button>
</form>
I need to get the id of an element within a form so I can tag the element as "false" or "true". Or, alternately, I need a way to associate a name with an element that can I pull in javascipt so I can change the associated value.
var form = document.getElementById("myForm");
form.elements[i].value
Those lines of code is what I tried but it doesn't seem to work.
Edit:
function initial(){
if (localStorage.getItem("run") === null) {
var form = document.getElementById("myForm").elements;
for(var i = 0; i < 1 ; i++){
var id = form.elements[i].id;
sessionStorage.setItem(id,"false");
}
localStorage.setItem("run", true);
}
}
So basically when I run the page, I want a localStorage item attached to all the buttons on the screen. I want this to run once so I can set all the items to false. Problem is I don't know how to get the ids so I have a value to attach to the button. Any idea of how to accomplish a task like this.
Edit2:
function initial(){
if (localStorage.getItem("run") === null) {
var form = document.getElementById("myForm");
var tot = document.getElementById("myForm").length;
for(var i = 0; i < tot ; i++){
sessionStorage.setItem(form.elements[i].id,"false");
}
localStorage.setItem("run", true);
}
}
This is the new code. It mostly seems to work but for some reason only the first value is getting set to false. Or maybe it has to do with this function, I'm not sure.
function loader(){
var form = document.getElementById("myForm");
var tot = 5;
for(var i = 0; i < 5 ; i++){
if(sessionStorage.getItem(form.elements[i].id) === "true"){
document.getElementById(form.elements[i].id).style.backgroundColor = "green";
return ;
}else{
document.getElementById(form.elements[i].id).style.backgroundColor = "red";
return false;
}
}
}
Anyways, I'm running both of these at the same time when the page is executed so they are all set to false and turn red. But when a button is properly completed, the color of the button turns green.
It's available via the id property on the element:
var id = form.elements[i].id;
More on MDN and in the spec.
Live Example:
var form = document.getElementById("myForm");
console.log("The id is: " + form.elements[0].id);
<form id="myForm">
<input type="text" id="theText">
</form>
You're already storing all the elements in the form so it must be :
var form = document.getElementById("myForm").elements;
var id = form[i].id;
Or remove the elements part from the form variable like :
var form = document.getElementById("myForm");
var id = form.elements[i].id;
I am trying to add a Mark all/Unmark all button in sub-list which is a type of inline-editor sub-list. below I have added a code for list type sub-list which will not work on inline-editor sub-list. Can anyone help to find this?
function button1Func(type) {
if (type=='edit' || 'view')
{
var record = nlapiLoadRecord(nlapiGetRecordType(), nlapiGetRecordId());
var intCount = record.getLineItemCount('item');
var headrow = document.getElementById("item_headerrow");
var head = headrow.insertCell(0);
head.innerHTML ="Select";
for (var rep = 1; rep <= intCount; rep++)
{
var row = document.getElementById("item_row_"+rep);
var x = row.insertCell(0);
var newCheckbox = document.createElement("INPUT");
newCheckbox.setAttribute("type", "checkbox");
newCheckbox.setAttribute("id", "select_CheckBox"+rep);
x.appendChild(newCheckbox);
}
}
}
function button2Func(type) {
if (type=='edit' || 'view')
{
var record = nlapiLoadRecord(nlapiGetRecordType(), nlapiGetRecordId());
var intCount = record.getLineItemCount('item');
for (var rep = 1; rep <= intCount; rep++)
{
var repId = record.getLineItemValue('item', 'item', rep);
if(document.getElementById("select_CheckBox"+rep).checked==true){
makecopyfun(repId);
}
else
{
continue;
}
}
alert("Success");
}
}
function makecopyfun(repId){
var record = nlapiLoadRecord(nlapiGetRecordType(), nlapiGetRecordId());
var intCount = record.getLineItemCount('item');
record.insertLineItem('item',intCount + 1);
alert (intCount);
record.setCurrentLineItemValue('item','item',repId);
record.commitLineItem('item');
var id = nlapiSubmitRecord(record, true);
}
Not sure through the API because there's no record object, you could try using jQuery.
First write following code & create userEvent script and apply function name(initnoload) in beforeLoad Event.
Then Deploy that script on Quote.
function initonload(type, form, request) {
if (type=='edit' || type=='view') {
var list = form.getSubList("item");
list.addButton('custpage_markmark','Mark all','markall();'); //markall(); is function name from the client script
list.addButton('custpage_unmarkmark','Unmark all','unmarkall();'); //unmarkall(); is function name from client script
form.setScript('customscript_mark_all_item_quote'); // 'customscript_mark_all_item_quote' is the ID of script
}
}
Above code will add two buttons to Sublist and their action get executed in client script whose ScriptId we have Defined.
Now write the following code & create client script.(Note: Just save the client script, Don't specify any event function name and do not deploy it).
function markall() {
var count=nlapiGetLineItemCount('item'); //gets the count of lines
for(var i=1;i<=count;i++) {
nlapiSelectLineItem('item',i);
nlapiSetCurrentLineItemValue('item','custcol_checkbox_field','T',true,true); //'custcol_checkbox_field' is checkbox's field ID.
}
nlapiCommitLineItem('item');
}
function unmarkall() {
var count=nlapiGetLineItemCount('item');
for(var i=1;i<=count;i++) {
nlapiSelectLineItem('item',i);
nlapiSetCurrentLineItemValue('item','custcol_checkbox_field','F',true,true); //'custcol_checkbox_field' is checkbox's field ID.
}
nlapiCommitLineItem('item');
}
After saving the client script please paste it's ID in user event's form.setScript('Client script ID'). function
i hope this will help you out.
Please let me know if u face any difficulty.
Thank you.
I do came up with other idea as you can use the field which'll help you to mark/unmark all lines under sublist..you can add subtab to the form and under subtab you can add field and sublist. later you can apply script on that field which will help you to mark/unmark all sublist lines.
Here is the code...
form.addSubTab('custpage_tab', 'Main Tab');
form.addField('custpage_chkmark','checkbox','Mark/Unmark All',null,'custpage_tab');
form.addSubList('custpage_sublst','inlineeditor','SampleSubList','custpage_tab');
im at javascript and dom. what i'd like to do with the below codes is when i append a tr and click the 2nd td (last name), the 2nd td value will be changed bold. then when i click the 2nd td value again, it will get back to normal. i've done with changing it bold but i cant make it go back to normal. i know if i add a button with onclick method calling detHandler. but i am not allowed to make a button for that. i need to click that name again to go back to normal. do you guys have any ideas?
<script type="text/javascript">
function appendUser()
{
var fname=prompt("Please enter your First Name");
var lname=prompt("Please enter your Last Name");
var email=prompt("Please enter your Email Address");
var table=document.getElementById("appendable");
var tr=document.createElement("tr");
var td1=document.createElement("td");
var td2=document.createElement("td");
td2.id="p1";
var td3=document.createElement("td");
td1.innerHTML = fname;
td2.innerHTML = lname;
td3.innerHTML = email;
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
tr.style.color="green";
table.appendChild(tr);
addHandler();
}
function addHandler ()
{
var addH = document.getElementById('p1');
if (addH.addEventListener)
{
addH.addEventListener('click', applyStyle, false);
}
else if (addH.attachEvent)
{
addH.attachEvent('onclick', applyStyle);
}
}
function detHandler ()
{
alert("aa");
var detH = document.getElementById('p1');
if (detH.removeEventListener)
{
detH.removeEventListener('click', applyStyle, false);
detH.style.color="blue";
//detH.style.fontWeight="normal";
}
else if (detH.detachEvent)
{
detH.detachEvent('onclick', applyStyle);
}
}
function applyStyle ()
{
var add = document.getElementById('p1');
add.style.fontWeight="bold";
}
</script>
</head>
<body>
<table id="appendable" width='50%' border='1'><tr><th>First Name</th><th>Last Name</th>
<th>Email Address</th></tr>
</tr></table>
<p><button onclick="appendUser()">Append New Row</button></p>
</body>
</html>'
Just toggle it in the handler
function applyStyle (){
var add = document.getElementById('p1');
var curr = add.style.fontWeight;
add.style.fontWeight = curr != 'bold' ? 'bold' : 'inherit';
}
FIDDLE
It is this line:
if (addH.addEventListener)
In the W3C model, you cannot find out whether an event is registered on an element or not.
You have duplicate IDs in your code (every row will have a cell with id="pq"!)
Consider this solution:
function appendUser()
{
var fname=prompt("Please enter your First Name");
var lname=prompt("Please enter your Last Name");
var email=prompt("Please enter your Email Address");
var table=document.getElementById("appendable");
var tr=document.createElement("tr");
var td1=document.createElement("td");
var td2=document.createElement("td");
var td3=document.createElement("td");
td1.appendChild(document.createTextNode(fname));
td2.appendChild(document.createTextNode(lname));
td2.setAttribute("data-toggleme","true"); // this is how we identify the cell
td3.appendChild(document.createTextNode(email));
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
tr.style.color="green";
table.appendChild(tr);
}
document.getElementById('appendable').onclick = function(e) {
e = e || window.event;
var t = e.srcElement || e.target;
while( t != this && t.nodeName != "TD") t = t.parentNode;
if( t.getAttribute("data-toggleme")) {
t.style.fontWeight = t.style.fontWeight == "bold" ? "" : "bold";
}
}
Deferring event handlers like this is great for two reasons:
Fewer event handlers! Makes the browser faster not having to keep track of so much.
It is future-proof in that you can add more rows and they will "automatically" be handled correctly
I am new to javascript and I can't populate many fields with one click.
<script>
function addTxt(txt, field)
{
var myTxt = txt;
var id = field;
document.getElementById(id).value = myTxt;
}
</script>
<input type="text" name="xx" id="info" autofocus="required">
<p>x</p>
I've got 3 more fields.
Thanks.
You can use
function addTxt(txt, ids)
{
for (var i=0, l=ids.length; i<l; ++i) {
document.getElementById(ids[i]).value = txt;
}
}
And call it like
addTxt('Some text', ['id1', 'id2', 'id3']);
You can populate multiple fields. I have shared a jsfiddle link. You can populate multiple fields using this code.
function addTxt(_val, _id,_no)
{
var _myTxt = _val;
var _id = _id;
for(var i=1;i<=_no;i++){
document.getElementById(_id+i).value = _myTxt;
}
}
Click here to see DEMO
I think you don't need a function to do this.
Just use
document.getElementById('id1').value
= document.getElementById('id2').value
= document.getElementById('id3').value
= 'Some text';
Or, if you think document.getElementById is too long, use a shortcut:
var get = document.getElementById;
/* ... */
get('id1').value = get('id2').value = get('id3').value = 'Some text';
Try getting the elements by tagName or by className instead of by id, then using a for loop to iterate through each one.