I have a function running onclick from HTML button and need to add disabling the button on success but NOT on return = false.
I've tried toggling, disabling directly in the HTML and inserting changing the HTML attribute within my current function.
var amtCount = 0;
function addToLineItem()
{
var totalAmount = 0.0;
var valid = true;
var difference = [];
$.each($(".tbodys tr"),function(index,vs)
{
for(var tdcnt = 0; tdcnt < vs.children.length - 1; tdcnt++)
{
if(tdcnt != 5)
if(vs.children[tdcnt].firstElementChild.value == "" || vs.children[tdcnt].firstElementChild.value == undefined)
valid = false;
}
if(vs.children[9].firstChild.value != "" && vs.children[9].firstChild.value != undefined)
{
RMID.push(vs.children[9].firstChild.value);
}
});
if(CodingListItem.length > 0)
{
difference = arr_diff(CodingListItem,RMID);
}
if(valid == false)
{
alert("Message");
return false;
}
if($("#aprDate").val() == "")
{
alert("Please date.");
return false;
}
$.each($(".tbodys tr .nine"),function(index,vs){
totalAmount += parseFloat(vs.firstElementChild.value.replace(/,/g, ""));
});
if($("#Total")[0].innerText == "")
{
alert("Please .");
return false;
}
//if(parseFloat($("#invTotal").val().replace(/,/g, "")) != totalAmount)
if(parseFloat($("#invTotal").val().replace(/,/g, "")) != parseFloat($("#Total")[0].innerText.replace(/,/g, "")))
{
alert("total amount does not match.");
return false;
}
SP.SOD.executeFunc("sp.js", 'SP.ClientContext', function()
{
try
{
var clientContext = SP.ClientContext.get_current();
var web = clientContext.get_web();
var oList = clientContext.get_web().get_lists().getByTitle('Invoice');
if(difference.length > 0)
{
$.each(difference, function( index, value )
{
deleteListItem(parseInt(value));
});
}
$.each($(".tbodys tr"),function(i,v)
{
if(v.children[9].firstChild.value != "" && v.children[9].firstChild.value != undefined)
{
var itemType1 = GetItemTypeForListName("InvoiceLineItem");
var item1 = {
"__metadata": { "type": itemType1 },
"Title": v.children[0].firstChild.value,
"InvoiceIDId": parseInt(INV),
"Entity": v.children[1].firstChild.value,
"MS": v.children[2].firstChild.value,
"LocationId": parseInt(v.children[3].firstChild.value),
"DepartmentId": parseInt(v.children[4].firstChild.value),
"Account": v.children[5].children[1].options[v.children[5].children[1].selectedIndex].text,
"SubAccount": v.children[6].firstChild.value,
"GLCode": v.children[7].firstChild.value,
"Amount": v.children[8].firstChild.value
};
updateListItem(parseInt(v.children[9].firstChild.value), "Invoice Approval and Coding", _spPageContextInfo.webAbsoluteUrl, item1, function () {
amtCount = amtCount + 1;
updatePendingInvoice(amtCount);
}, function () { errorMsg = true; });
}
else
{
var itemCreateInfo = new SP.ListItemCreationInformation();
var oListItem = oList.addItem(itemCreateInfo);
oListItem.set_item('Title', v.children[0].firstChild.value); //Line Description
oListItem.set_item('InvoiceID', INV);
oListItem.set_item('Entity', v.children[1].firstChild.value);
oListItem.set_item('MS', v.children[2].firstChild.value);
oListItem.set_item('Location', v.children[3].firstChild.value);
oListItem.set_item('Department', v.children[4].firstChild.value);
oListItem.set_item('Account', v.children[5].children[1].options[v.children[5].children[1].selectedIndex].text);
oListItem.set_item('SubAccount', v.children[6].firstChild.value);
oListItem.set_item('GLCode', v.children[7].firstChild.value);
oListItem.set_item('Amount', v.children[8].firstChild.value);
oListItem.set_item('Date', $("#aprDate").val());
oListItem.set_item('Comment', $("#cmt").val());
oListItem.update();
clientContext.executeQueryAsync(onQuerySucceeded, onQueryFailed);
}
});
}
catch(err)
{
alert(err.message);
}
});
}
function onQuerySucceeded()
{
amtCount = amtCount + 1;
updatePendingInvoice(amtCount);
}
function onQueryFailed(sender, args)
{
alert('not inserted');
}
This runs fine but if the HTML Button is clicked quickly, the function runs and creates duplicate data.
You should disable the button while you are acting on the click. Then the user cannot queue up another update until the first one finishes. Set an internal variable saying that the work is in progress, disable the button, and then clear the flag when you get the result (success or fail).
For instance:
$("#btnSubmit").click(function() {
$("#btnSubmit").prop("disabled", true);
// do your work here, waiting for success or failure
$('#btnSubmit').prop("disabled", false);
})
or:
$("button").click(function(e) {
$(e.currentTarget).prop('disabled', true);
window.setTimeout(function() {
$(e.currentTarget).prop('disabled', false);
}, 5000);
})
I found what I needed and with some experimentation with where to put the "disabled", false lines was able to get to the solution. I got the simple code from Palash
https://stackoverflow.com/users/1823841/palaѕн
All versions of jQuery after 1.6
Disabling and enabling a html input button
Thank you all for helping... New Code....
var amtCount = 0;
function addToLineItem()
{
**$("#IApprove").attr("disabled", true);**
var totalAmount = 0.0;
var valid = true;
var difference = [];
$.each($(".tbodys tr"),function(index,vs)
{
for(var tdcnt = 0; tdcnt < vs.children.length - 1; tdcnt++)
{
if(tdcnt != 5)
if(vs.children[tdcnt].firstElementChild.value == "" || vs.children[tdcnt].firstElementChild.value == undefined)
valid = false;
}
if(vs.children[9].firstChild.value != "" && vs.children[9].firstChild.value != undefined)
{
RMID.push(vs.children[9].firstChild.value);
}
});
if(CodingListItem.length > 0)
{
difference = arr_diff(CodingListItem,RMID);
}
if(valid == false)
{
alert("Please add Line Items with Required Information. GL coding missing.");
**$("#IApprove").attr("disabled", false);**
return false;
}
if($("#aprDate").val() == "")
{
alert("Please add approver date.");
**$("#IApprove").attr("disabled", false);**
return false;
}
$.each($(".tbodys tr .nine"),function(index,vs){
totalAmount += parseFloat(vs.firstElementChild.value.replace(/,/g, ""));
});
if($("#Total")[0].innerText == "")
{
alert("Please add Line items.");
**$("#IApprove").attr("disabled", false);**
return false;
}
//if(parseFloat($("#invTotal").val().replace(/,/g, "")) != totalAmount)
if(parseFloat($("#invTotal").val().replace(/,/g, "")) != parseFloat($("#Total")[0].innerText.replace(/,/g, "")))
{
alert("Line item's total amount does not match with total invoice amount.");
**$("#IApprove").attr("disabled", false);**
return false;
}
SP.SOD.executeFunc("sp.js", 'SP.ClientContext', function()
{
try
{
var clientContext = SP.ClientContext.get_current();
var web = clientContext.get_web();
var oList = clientContext.get_web().get_lists().getByTitle('Invoice Approval and Coding');
///////////// Delete Items //////////////////
if(difference.length > 0)
{
$.each(difference, function( index, value )
{
deleteListItem(parseInt(value));
});
}
$.each($(".tbodys tr"),function(i,v)
{
if(v.children[9].firstChild.value != "" && v.children[9].firstChild.value != undefined)
{
var itemType1 = GetItemTypeForListName("InvoiceLineItem");
var item1 = {
"__metadata": { "type": itemType1 },
"Title": v.children[0].firstChild.value,
"InvoiceIDId": parseInt(INV),
"Entity": v.children[1].firstChild.value,
"MS": v.children[2].firstChild.value,
"LocationId": parseInt(v.children[3].firstChild.value),
"DepartmentId": parseInt(v.children[4].firstChild.value),
"Account": v.children[5].children[1].options[v.children[5].children[1].selectedIndex].text,
"SubAccount": v.children[6].firstChild.value,
"GLCode": v.children[7].firstChild.value,
"Amount": v.children[8].firstChild.value
};
updateListItem(parseInt(v.children[9].firstChild.value), "Invoice Approval and Coding", _spPageContextInfo.webAbsoluteUrl, item1, function () {
amtCount = amtCount + 1;
updatePendingInvoice(amtCount);
}, function () { errorMsg = true; });
}
else
{
var itemCreateInfo = new SP.ListItemCreationInformation();
var oListItem = oList.addItem(itemCreateInfo);
oListItem.set_item('Title', v.children[0].firstChild.value); //Line Description
oListItem.set_item('InvoiceID', INV);
oListItem.set_item('Entity', v.children[1].firstChild.value);
oListItem.set_item('MS', v.children[2].firstChild.value);
oListItem.set_item('Location', v.children[3].firstChild.value);
oListItem.set_item('Department', v.children[4].firstChild.value);
oListItem.set_item('Account', v.children[5].children[1].options[v.children[5].children[1].selectedIndex].text);
oListItem.set_item('SubAccount', v.children[6].firstChild.value);
oListItem.set_item('GLCode', v.children[7].firstChild.value);
oListItem.set_item('Amount', v.children[8].firstChild.value);
oListItem.set_item('Date', $("#aprDate").val());
oListItem.set_item('Comment', $("#cmt").val());
oListItem.update();
clientContext.executeQueryAsync(onQuerySucceeded, onQueryFailed);
}
});
}
catch(err)
{
alert(err.message);
}
});
}
I have created the below code for a subscribe form and for the most part it is working fine apart from, however the following condition does not seem to be working:
if (subFieldUpdated === true && subValidEmail === true) {
$("#modEmailSub, #modFNameSub, #modLNameSub").val("");
}
What is happening is that when the subValidEmail is entered correctly it clears all of the other entered data which leads me to believe that the subFieldUpdated === true condition is not being picked up correctly?
What I am looking for is that the form will only clear the values once all fields have been entered & a valid email is present.
Any suggestions/advice would be great as I have tried a few things now but with no luck.
$("#modSubCard").submit(function() {
var modSubField = ["#modEmailSub", "#modFNameSub", "#modLNameSub"];
$("#modEmailSub, #modFNameSub, #modLNameSub").removeClass("border-red");
contactValid(modSubField);
function contactValid(field) {
var subFieldUpdated = true;
var subValidEmail = true;
for (var i = 0; i < field.length; i++) {
if ($(field[i]).val() == "") {
$(field[i]).addClass("border-red");
subFieldUpdated[i] = false;
}
if (!validateEmail($("#modEmailSub").val())) {
$("#modEmailSub").addClass("border-red");
subValidEmail = false;
}
if (subFieldUpdated === true && subValidEmail === true) {
$("#modEmailSub, #modFNameSub, #modLNameSub").val("");
}
}
}
});
Use Below Code. It will works for you.
var modSubField = ["#modEmailSub", "#modFNameSub", "#modLNameSub"];
$("#modEmailSub, #modFNameSub, #modLNameSub").removeClass("border-red");
contactValid(modSubField);
function contactValid(field) {
var subFieldUpdated = 0;
var subValidEmail = true;
for (var i = 0; i < field.length; i++) {
if ($(field[i]).val() == "") {
$(field[i]).addClass("border-red");
subFieldUpdated = subFieldUpdated + 1;
}
if (!validateEmail($("#modEmailSub").val())) {
$("#modEmailSub").addClass("border-red");
subValidEmail = false;
}
if (subFieldUpdated === 0 && subValidEmail === true) {
$("#modEmailSub, #modFNameSub, #modLNameSub").val("");
}
}
}
});
I am trying to make a form validate where there are radio buttons and textarea. I want nothing to be left empty i.e the form should be completely filled. I have done the radio buttons part of validation where if a user does not select a radio button he will get an error for that particular question. you can see the code here for detailed code.
Please help me out. I am not getting error for textarea.
Just add another check for textarea
function RadioValidator() {
var ShowAlert = '';
var AllFormElements = window.document.getElementById("FormID").elements;
for (i = 0; i < AllFormElements.length; i++) {
var name = AllFormElements[i].name;
if (AllFormElements[i].type == 'radio') {
....
} else if (AllFormElements[i].type == 'textarea') {
if (AllFormElements[i].value == '') {
ShowAlert += name + ' textarea must be filled\n';
}
}
}
if (ShowAlert !== '') {
alert(ShowAlert);
return false;
} else {
return true;
}
}
you didn't write any validation for 'textarea' block. I have updated it with one textarea... add rest validations.
function RadioValidator()
{
var ShowAlert = '';
var AllFormElements = window.document.getElementById("FormID").elements;
for (i = 0; i < AllFormElements.length; i++)
{
if (AllFormElements[i].type == 'radio')
{
var ThisRadio = AllFormElements[i].name;
var ThisChecked = 'No';
var AllRadioOptions = document.getElementsByName(ThisRadio);
var problem_desc = document.getElementById("problem_desc");
for (x = 0; x < AllRadioOptions.length; x++)
{
if (AllRadioOptions[x].checked && ThisChecked === 'No' && problem_desc.value === "")
{
ThisChecked = 'Yes';
break;
}
}
var AlreadySearched = ShowAlert.indexOf(ThisRadio);
if (ThisChecked == 'No' && AlreadySearched == -1 && problem_desc.value === "")
{
ShowAlert = ShowAlert + ThisRadio + ' option must be selected\n';
}
}else if(AllFormElements[i].type =='textarea')
{
// add your rest of text area validations here
var problem_desc_1 = document.getElementById("problem_desc");
if(problem_desc_1.value === "")
{
ShowAlert = ShowAlert + '"Services (Please Specify)" can not be blank. \n';
}
}
}
if (ShowAlert !== '')
{
alert(ShowAlert);
return false;
}
else
{
return true;
}
}
You need to add a check for textarea as well
In your javascript check you have only added a condition for type radio.
check for textarea type as well and add error if the value is blank.
I wrote a function to remove accounts name relate field from Contacts QuickCreate but my function works in Firefox perfectly but in chrome its not working... Here is my function
function manageRequired(reqArr, disabledVal)
{
var requiredLabel = '<span class="required">*</span>'; // for firefox
var search_requiredLabel = '<span class="required"'; // searching string for firefox
var form = "";
for(var i = 0; i < document.forms.length; i++)
{
if(document.forms[i].id=='EditView')
{
form = 'EditView';
break;
}
if(document.forms[i].id=='form_SubpanelQuickCreate_Contacts')
{
form = 'form_SubpanelQuickCreate_Contacts';
break;
}
if(document.forms[i].id=='form_QuickCreate_Contacts')
{
form = 'form_QuickCreate_Contacts';
break;
}
if(document.forms[i].id=='form_QuickCreate_Accounts')
{
form = 'form_QuickCreate_Accounts';
break;
}
}
for(var j = 0; j < reqArr.length; j++)
{
var flag = true;
if (validate[form] != 'undefined')
{
for(var i = 0; i < validate[form].length; i++)
{
if(validate[form][i][0] == reqArr[j].id && validate[form][i][2])
{
if(disabledVal)
{
flag = false;
break;
}
else
{
validate[form][i][2] = false;
}
}
}
}
var labelNode = document.getElementById(reqArr[j].id + '_label');
if(flag & disabledVal)
{
// we require the field now
addToValidate(form, reqArr[j].id, reqArr[j].type, true,reqArr[j].label );
}
if(disabledVal)
{
if(labelNode != null && labelNode.innerHTML.indexOf(search_requiredLabel) == -1) // for IE replace search string
{
search_requiredLabel = '<SPAN class=required>';
}
if (labelNode != null && labelNode.innerHTML.indexOf(search_requiredLabel) == -1)
{
labelNode.innerHTML = labelNode.innerHTML.replace(requiredLabel, '');
labelNode.innerHTML = labelNode.innerHTML + requiredLabel;
}
}
else
{
if(labelNode != null)
{
if(labelNode != null && labelNode.innerHTML.indexOf("<SPAN class=required>*</SPAN>") == -1 && labelNode.innerHTML.indexOf('<span class="required">*</span>') == -1 )// for that field which is unrequired
{
}
else if(labelNode != null && labelNode.innerHTML.indexOf(requiredLabel) == -1) // for IE replace span string
{
requiredLabel = "<SPAN class=required>*</SPAN>";
}
labelNode.innerHTML = labelNode.innerHTML.replace(requiredLabel, '');
}
}
}
}
Can anyone please help me out to solve this issue...
To remove a required field from QuickCreate in Sugarcrm you can use this fuction:
removeFromValidate('EditView','eventlist_c');
or remove remove the validtion applied to the field:
$('#eventlist_c_label').html('{$mod_strings['LBL_EVENTLIST']}: ');
I have a form with a validation script that works perfectly. I would however like the form to jump to the fields that doesn't validate or display the name of the fields in the error message.
The code I use to validate is:
else
{
var valid = document.formvalidator.isValid(f);
}
if (flag == 0 || valid == true) {
f.check.value = '<?php echo JUtility::getToken(); ?>';//send token
}
else {
alert('There was an error with the fields..');
return false;
}
return true;
How can I get the alert to name the fields that need to be filled in correctly or jump to the specific field?
Edited ----------
Hi,
Thanks for help so far. I'm very new to JS. The form is in a component of Joomla.
The full function that validates the form is
function validateForm(f){
var browser = navigator.appName;
if (browser == "Microsoft Internet Explorer"){
var flag = 0;
for (var i=0;i < f.elements.length; i++) {
el = f.elements[i];
if ($(el).hasClass('required')) {
var idz= $(el).getProperty('id');
if(document.getElementById(idz)){
if (!document.getElementById(idz).value) {
document.formvalidator.handleResponse(false, el);
flag = flag + 1;
}
}
}
}
}
else {
var valid = document.formvalidator.isValid(f);
}
if(flag == 0 || valid == true){
f.check.value='<?php echo JUtility::getToken(); ?>';//send token
}
else {
alert('<?php echo JText::_('JBJOBS_FIEDS_HIGHLIGHTED_RED_COMPULSORY'); ?>');
return false;
}
return true;
}
External js file:
var JFormValidator = new Class(
{
initialize : function() {
this.handlers = Object();
this.custom = Object();
this.setHandler("username", function(b) {
regex = new RegExp("[<|>|\"|'|%|;|(|)|&]", "i");
return !regex.test(b)
});
this.setHandler("password", function(b) {
regex = /^\S[\S ]{2,98}\S$/;
return regex.test(b)
});
this.setHandler('passverify',
function (value) {
return ($('password').value == value);
}
); // added March 2011
this.setHandler("numeric", function(b) {
regex = /^(\d|-)?(\d|,)*\.?\d*$/;
return regex.test(b)
});
this
.setHandler(
"email",
function(b) {
regex = /^[a-zA-Z0-9._-]+(\+[a-zA-Z0-9._-]+)*#([a-zA-Z0-9.-]+\.)+[a-zA-Z0-9.-]{2,4}$/;
return regex.test(b)
});
var a = $$("form.form-validate");
a.each(function(b) {
this.attachToForm(b)
}, this)
},
setHandler : function(b, c, a) {
a = (a == "") ? true : a;
this.handlers[b] = {
enabled : a,
exec : c
}
},
attachToForm : function(a) {
a.getElements("input,textarea,select")
.each(
function(b) {
if (($(b).get("tag") == "input" || $(b)
.get("tag") == "button")
&& $(b).get("type") == "submit") {
if (b.hasClass("validate")) {
b.onclick = function() {
return document.formvalidator
.isValid(this.form)
}
}
} else {
b.addEvent("blur", function() {
return document.formvalidator
.validate(this)
})
}
})
},
validate : function(c) {
c = $(c);
if (c.get("disabled")) {
this.handleResponse(true, c);
return true
}
if (c.hasClass("required")) {
if (c.get("tag") == "fieldset"
&& (c.hasClass("radio") || c.hasClass("checkboxes"))) {
for ( var a = 0;; a++) {
if (document.id(c.get("id") + a)) {
if (document.id(c.get("id") + a).checked) {
break
}
} else {
this.handleResponse(false, c);
return false
}
}
} else {
if (!(c.get("value"))) {
this.handleResponse(false, c);
return false
}
}
}
var b = (c.className && c.className
.search(/validate-([a-zA-Z0-9\_\-]+)/) != -1) ? c.className
.match(/validate-([a-zA-Z0-9\_\-]+)/)[1]
: "";
if (b == "") {
this.handleResponse(true, c);
return true
}
if ((b) && (b != "none") && (this.handlers[b])
&& c.get("value")) {
if (this.handlers[b].exec(c.get("value")) != true) {
this.handleResponse(false, c);
return false
}
}
this.handleResponse(true, c);
return true
},
isValid : function(c) {
var b = true;
var d = c.getElements("fieldset").concat($A(c.elements));
for ( var a = 0; a < d.length; a++) {
if (this.validate(d[a]) == false) {
b = false
}
}
new Hash(this.custom).each(function(e) {
if (e.exec() != true) {
b = false
}
});
return b
},
handleResponse : function(b, a) {
if (!(a.labelref)) {
var c = $$("label");
c.each(function(d) {
if (d.get("for") == a.get("id")) {
a.labelref = d
}
})
}
if (b == false) {
a.addClass("invalid");
a.set("aria-invalid", "true");
if (a.labelref) {
document.id(a.labelref).addClass("invalid");
document.id(a.labelref).set("aria-invalid", "true");
}
} else {
a.removeClass("invalid");
a.set("aria-invalid", "false");
if (a.labelref) {
document.id(a.labelref).removeClass("invalid");
document.id(a.labelref).set("aria-invalid", "false");
}
}
}
});
document.formvalidator = null;
window.addEvent("domready", function() {
document.formvalidator = new JFormValidator()
});
Where would I edit the code as some of you have answered below?
with jquery js library, scroll to element (id selector or class)
<p class="error">There was a problem with this element.</p>
This gets passed to the ScrollTo plugin in the following way.
$.scrollTo($('p.error:1'));
see source
Using jQuery's .each, loop over the fields. On every iteration the item that is being invesitigated will be under the this variable.
Therefore, this.id gives the id of the element you're looking for. Store these to collect all the incorrect fields, then highlight them or print their names in a message.
Keep in mind, this is the basic idea, I cannot give an actual answer until you show the code that handles the form.
Kind regards,
D.
You can have your isValid routine return the error message instead of returning a boolean.
In isValid, you can build up the error message to include the field names with errors.
Instead of checking "valid == true", you will check "errorMessage.length == 0".
If you want to focus on an error field (you can only focus on one), then do that in the isValid routine as well.
function isValid(f) {
var errorMessage = "";
var errorFields = "";
var isFocused = false;
...
if (field has an error) {
errorFields += " " + field.name;
if (!isFocused) {
field.focus();
isFocused = true;
}
}
...
if (errorFields.length > 0) {
errorMessage = "Errors in fields: " + errorFields;
}
return (errorMessage);
}
then, in your calling routine:
var errorMessage = isValid(f);
if (flag == 0 || errorMessage.length == 0) {
f.check.value='<?php echo JUtility::getToken(); ?>';//send token
}
else {
alert(errorMessage);
return false;
}
return true;