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 a lot of labels as shown on a page. I want to sum the values and store them in final_cpa.
HTML :
<label class="tmpcpa">32.1</label>
JS :
function calculate_final_cpa() {
var final_cpa = 0;
var allfilled = false;
$('.tmpcpa').each(function () {
if ($(this).val() != 0) {
final_cpa += parseInt($(this).text()) || 0;
allfilled = true;
} else {
allfilled = false;
}
});
console.log(final_cpa);
console.log(allfilled);
}
var run = setInterval(calculate_final_cpa, 500);
However final_cpa is always 0 and allfilled remains false.
That because label don't have a value attribute so the .val() function will always return an empty string, you have to use .text() instead to get the text content inside the label element :
if ($(this).val() != 0) {
Should be :
if ($(this).text() != 0) {
NOTE : as Rayon mentioned in the comment below text() will always return string so better to change the zero in condition to string '0'.
Hope this helps.
function calculate_final_cpa() {
var final_cpa = 0;
var allfilled = false;
$('.tmpcpa').each(function () {
if ($(this).text() != '0') {
final_cpa += parseInt($(this).text()) || 0;
allfilled = true;
} else {
allfilled = false;
}
});
console.log(final_cpa);
console.log(allfilled);
}
calculate_final_cpa();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label class="tmpcpa">32.1</label>
Check $(this).text() != "" instead of $(this).val() != 0 as You can not use .val() for getting label text. .text() will give you text of label
if ($(this).text() != "" && $(this).text() != "0") {
....
}
First thing, you need to use .text() instead of .val() to get the text inside a label. Also, if you are expecting your result to contain decimal digits, you need to use parseFloat():
function calculate_final_cpa() {
var final_cpa = 0;
var allfilled = false;
$('.tmpcpa').each(function () {
if ($(this).text() != 0) {
final_cpa += parseFloat($(this).text()) || 0;
allfilled = true;
} else {
allfilled = false;
}
});
console.log(final_cpa);
console.log(allfilled);
}
calculate_final_cpa();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<label class="tmpcpa">32.1</label>
<br />
<label class="tmpcpa">32.1</label>
Change
if ($(this).val() != 0)
to
if (parseInt($(this).text()) != 0)
Beside your code had an error, you should check the content of the table before parsing them. And because you use decimals in your example, you should switch from parseInt to parseFloat too.
And your allfilled varibale makes no sense, because if the last element of .tmpcpa was empty, it will be false again. So i removed it.
function calculate_final_cpa() {
var final_cpa = 0;
$('.tmpcpa').each(function () {
var content = $(this).text();
final_cpa += IsNumeric(content) ? parseFloat(content) : 0;
});
console.log(final_cpa);
}
Test it with .text instead of val() as label has no value property
Use Unary plus(+)/Number operator instead of parseInt as parseInt will ignore floating point
Use length of lable-elements to test whether all the label has values !== 0
function calculate_final_cpa() {
var final_cpa = 0;
var countOfFilled = 0;
$('.tmpcpa').each(function() {
if ($(this).text() !== '0') {
final_cpa += +($(this).text()) || 0;
++countOfFilled;
}
});
console.log('Total: ' + final_cpa);
console.log('All filled ' + $('.tmpcpa').length === countOfFilled);
}
calculate_final_cpa();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<label class="tmpcpa">32.1</label>
<label class="tmpcpa">32.1</label>
<label class="tmpcpa">0</label>
As the title describes, I'm having a problem with a function running using the
$("element_name").on("change", some_function)
event on a select when manually setting the element's value like
$("element_name").val("")
I read something about a "chosen" and I don't understand what that has anything to do with the issue.
Anybody know why the on.change() handler isn't catching the manual value change?
EDIT: I am including additional information as the solutions suggested do not work.
trigger("change"), bind("change", and on("change") do not work.
This is the code for the recreated select that controls the value setting:
(function($) {
$.extend({
fancySelect: function(options) {
var defaults = {
autoClose: true
}
var options = $.extend(defaults, options);
$("select").hide();
$("select").each(function() {
var $select = $(this);
var $fancyselect = $('<div class="fancyselect"/>');
$select.after($fancyselect);
var $ul = $('<ul/>').appendTo($fancyselect);
$ul.hide();
var $options = $select.find("option");
var $span = $("<div/>").addClass("fancyselect-label").prependTo($fancyselect);
var $arrow = $("<div>▼</div>").addClass("fancyselect-arrow").appendTo($fancyselect);
var selected = $select.find("option[selected=selected]");
var toUse = 0;
if (selected.length == 0) {
toUse = $options.first();
} else {
toUse = selected.first();
}
$span.text(toUse.text());
$options.each(function() {
var $option = $(this);
var label = $option.text();
var value = $option.val();
if ($option.is(":selected")) {
$span.text(label);
}
var $li = $('<li value="' + value + '">' + label + '</li>').appendTo($ul).bind("click", function() {
$select.val(value);
if ($option.index() == $(this).index()) {
$options.removeAttr("selected");
$option.attr("selected", "selected");
}
$span.html(label);
if (options.autoClose) {
$ul.hide();
$fancyselect.removeClass("active");
}
$ul.find("li").removeAttr("class");
$(this).addClass("selected");
});
if ($option.is(":selected")) {
$li.addClass("selected");
}
});
if (!$select.attr("disabled")) {
var $j = 0;
$span.bind("click", function() {
if ($ul.is(":visible")) {
$ul.hide();
$fancyselect.removeClass("active");
$arrow.html("▼");
} else {
$(".fancyselect").each(function() {
$(this).find("ul").hide();
$(this).removeClass("active");
});
$ul.show();
$fancyselect.addClass("active");
$arrow.html("▼");
if ($j == 0) $ul.tinyScrollbar();
$j++;
}
});
} else {
$fancyselect.addClass("disabled");
}
});
$(document).bind("keyup keydown keypress", function(event) {
$(".fancyselect").each(function() {
var $ul = $(this).find("ul");
if ($ul.is(":visible")) {
var keycode = parseInt((event.keyCode ? event.keyCode : event.which));
if(keycode >= 48 && keycode <= 90){
$ul.find("li").each(function() {
if ($(this).text().substr(0, 1) == String.fromCharCode(event.keyCode)) {
$ul.find("li").removeAttr("class");
$(this).addClass("selected");
return;
}
});
} else if (keycode == 13) {
$ul.hide();
}
return;
}
});
});
}
});
})(jQuery);
$.fancySelect();
And this is the code for the binding:
$(".downloads-series-sort select").trigger("change", load_downloads);
I have 5 select fields with id's id1, id2,.. id5
and i need check if values (selected) not equal then highlight green and if equal then highlight red
but is look crazy validate each field 5 times? is posible use special functions ir validate easy than with:
if
if
if
if
I dont need a code just idea.
You can loop through each select to compare the values
$("select").change(function () {
flag = false;
var value = $(this).val();
$("select").each(function () {
if ($(this).val() != value)
flag = true;
});
if (flag)
$("select").css("color", "red");
else
$("select").css("color", "green");
});
Demo
Edit
$("select").change(function () {
var flag = true;
$("select").each(function () {
var outer = this;
$("select").not(outer).each(function () {
if ($(outer).val() == $(this).val()) {
flag = false;
return false;
}
});
});
if (flag)
$("select").css("color", "green");
else
$("select").css("color", "red");
});
Updated Fiddle
New update
I've simplified the code like this. YOu dont have to use nested loop if you do like this
$("select").change(function () {
var flag = true;
$("select").each(function () {
if ($("select").find("option:selected[value=" + this.value + "]").length > 1) {
flag = false;
return false;
}
});
if (flag)
$("select").css("color", "green");
else
$("select").css("color", "red");
});
Updated Fiddle
Try this one..
$("select").change(function(){
var selected = [];
var valiSel = [];
$('select > option:selected').each(function() {
if($(this).val() != 0){
selected.push( $(this).val() );
}
valiSel.push( $(this).val() );
});
var unique = unique12(selected);
var uniqueLength = unique.length;
var valiSelUnique = unique12(valiSel);
var selectedLength = selected.length;
if( unique.length != selected.length ){
alert( 'Two Selected value cannot be same' );
return false;
}
//return true;
});
function unique12(sel) {
var r = new Array();
o:for(var i = 0, n = sel.length; i < n; i++)
{
for(var x = 0, y = r.length; x < y; x++)
{
if(r[x]==sel[i])
{
//alert('this is a DUPE!');
continue o;
}
}
r[r.length] = sel[i];
}
return r;
}
DEMO
$('#container form').delegate('#addSearch', 'keyup', function(e) {
var tmpVAL = $('#addSearch').val();
$('.w').each(function() {
var tmpHTML = $(this).html();
if (tmpHTML == tmpVAL) {
$(this).fadeIn(250);
} else if (tmpVAL.length < 1) {
$(this).fadeIn(250);
} else {
$(this).fadeOut(250);
}
});
});
and #addSearch is an <input type="text">.
So, my problem is that; this obviously will only return the results that are an exact match to the tmpVAL - How would I allow it so every letter will change the search result.
e.g.
I type N
it comes up with No, Not, Nothing, Nothingness
I type NOT
it comes up with Not, Nothing, Nothingness
Any help would be appreciated, I would imagine that it would be RegEx?
DEMO https://so.lucafilosofi.com/autocomplete-autofilter-using-jquery-delegate
$(function() {
$('#container form').delegate('#addSearch', 'keyup', function(e) {
var tmpVAL = $('#addSearch').val();
$('.w').each(function() {
var tmpHTML = $(this).text();
var subSection = tmpHTML.substring(tmpVAL.length, 0);
if (subSection == tmpVAL && tmpVAL != '' ) {
$(this).show();
} else {
$(this).hide();
}
});
});
});
You could use a regular expression, but I think that might be overkill. You could just use indexOf:
$('#container form').delegate('#addSearch', 'keyup', function(e) {
var tmpVAL = $('#addSearch').val().toLowerCase();
$('.w').each(function() {
var tmpHTML = $(this).html().toLowerCase();
if (tmpHTML.indexOf(tmpVAL) >= 0) {
$(this).fadeIn(250);
} else if (tmpVAL.length < 1) {
$(this).fadeIn(250);
} else {
$(this).fadeOut(250);
}
});
});
Working example: http://jsfiddle.net/andrewwhitaker/PRyvU/
Here's an alternative solution that doesn't use an .each():
$('#container form').delegate('#addSearch', 'keyup', function(e) {
var tmpVAL = $('#addSearch').val().toLowerCase();
var $words = $(".w");
var contains = function(haystack, needle) {
return haystack.indexOf(needle) >= 0;
};
if (tmpVAL.length < 1) {
$words.fadeIn(250);
}
else {
$words.filter(function() {
return !contains($(this).html().toLowerCase(), tmpVAL);
}).fadeOut(250);
$words.filter(function() {
return contains($(this).html().toLowerCase(), tmpVAL);
}).fadeIn(250);
}
});
http://jsfiddle.net/andrewwhitaker/EyJ6b/