With jQuery how do I change the class of a read-only input field in real-time if it's value becomes negative or positive?

I have a formula made with jcalx on http://demo.missionfamily.org/formula/

There is a read-only field marked ##A13## which displays calculations based on other fields of the equation.
The values in that field are either negative or positive depending on whether the company is making profit or loss.

What I would like to do it make it's background red when the value in it becomes negative and return it to normal when it is positive (basically assign it a class in real-time and take it out in the same way).

If you follow this example you can get positive or negative results:

1.

When you load the page the value is positive so set class 'positive'

2.

Just change the value ni ##A9## to 20 and the value in ##A13## will become negative so set class negative
Please remember that various other combinations of the formula would produce negative results in ##A13## so all have to be considered. Realistically I need the check to be made onBlur of every field that can be edited.

thanks in advance
badwolfffAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Julian HansenCommented:
So if I understand you, you want to check each text box when a change is made to any text box and set the corresponding <span> that contains the text box to red when the value of the text box is < 0.

So something like this (off the top of my head - I have not tested it so you might have to tweak it)
$('input[type=text]').blur(function() {
  $('input[type=text]:disabled').each(function() {
      if (parseFloat($(this).val()) < 0) {
          $(this).closest('span').addClass('showred');
      }
     else {
          $(this).closest('span').removeClass('showred');
    }
  });
});

Open in new window

0
badwolfffAuthor Commented:
Thanks for the answer. You are slightly off. I need to test all fields for input but the only field that needs to be set as red (class set to negative) or not (class set to positive) is the A13 field ONLY if its value is negative.
0
badwolfffAuthor Commented:
Basically any time value in field A13 becomes negative add class "negative" and when it becomes positive add class "positive".

Of course a value change in A13 can only occur if any of the other field values are updated.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Julian HansenCommented:
I need to test all fields for input but the only field that needs to be set as red (class set to negative) or not (class set to positive) is the A13 field ONLY if its value is negative.

So what you are saying is always check A13 on a blur of any field
Then how about this

$('input[type=text]').blur(function() {
    if ($('#guadagno').val() < 0) {
       $('#guadagnovero').addClass('showred');
    }
    else {
       $('#guadagnovero').removeClass('showred');
    }
});

Open in new window

0
badwolfffAuthor Commented:
Hi,

I tried it. Doesn't work. Also you are considering only the inputs of text type, what about other input types like selectors?

I made a few modifications to your code and still it doesn't work properly - sometimes it does and sometimes it doesn't.
$('input, select').blur(function() {
	window.console&&console.log('form updated');
    if ($('#guadagno').val() < 0) {
		window.console&&console.log('value less than 0');
		$('#guadagno').css({'color':'#fff','background-color':'#F00'});
    }
    else {
		window.console&&console.log('value more than 0');
       $('#guadagno').css({'color':'#666','background-color':'#F0F0F0'});
    }
});	

Open in new window


Try it online on my site please.

If you put in a value or select any dropdown that makes the value in A13 negative, the first time the console log tells that the value is still positive even though the value is negative. If you then go and do anything else that will keep the value negative it will turn red. And vice versa. So I have a feeling that the IF/ELSE are happening too fast. Maybe a delay might help? Any suggestions?
0
badwolfffAuthor Commented:
Attaching files here: formula.zip
0
Julian HansenCommented:
The blur is happening before the change.

What you need to do is trigger a change event after setting the value for A13.

Where is the code that is setting the Value of A13?
0
Julian HansenCommented:
.. forgot to add - once you have found that you can do a trigger change on this code

	$('#guadagno').change(function() {
		if (parseFloat($(this).val()) < 0) {
			$(this).closest('span').addClass('showred');
		}
		else {
			$(this).closest('span').removeClass('showred');
		}
	});

Open in new window

0
badwolfffAuthor Commented:
A13 input filed has a data-formula:

<input id="guadagno" type="text" data-cell="A13" data-format="0,0.00" data-formula="(((A2/A4)*A6)*(1-  ((SUM(A7:A9)) + (A10*A32*A33))  ))-(A2/A4)-A12" disabled>

That is setting its value using jquery calx.
0
badwolfffAuthor Commented:
Thanks. I used your idea and applied it laterally with an idea of mine and it works now.
Your code did not work out of the box as it failed to indicate when value in A13 was changing.

This is how I did it:

/* START: If client is losing money set guadagno to red */
function checkGuadagno(selector, callback) {
   invalue = $(selector);
   existingvalue = invalue.val();
   setInterval(function(){
	  if (invalue.val()!=existingvalue){
		  existingvalue = invalue.val();
		  callback();
	  }
   }, 100);
}

checkGuadagno('#guadagno', function()
{
	window.console&&console.log('form updated');
	if (parseFloat($('#guadagno').val()) < 0) {
		window.console&&console.log('value less than 0');
		$('#guadagno').css({'color':'#fff','background-color':'#F00', 'border':'1px solid #999'});
	}
	else {
		window.console&&console.log('value more than 0');
		$('#guadagno').css({'color':'#666','background-color':'#F0F0F0', 'border':'1px solid #999'});
	}
});
/* END: If client is losing money set guadagno to red */

Open in new window

0
badwolfffAuthor Commented:
I've requested that this question be closed as follows:

Accepted answer: 0 points for badwolfff's comment #a40834524
Assisted answer: 500 points for Julian Hansen (JulianH)'s comment #a40834449

for the following reason:

I used an idea that was suggested and made it work with my own code.
0
Julian HansenCommented:
Your code did not work out of the box as it failed to indicate when value in A13 was changing.
That was because the calc does not fire a change event on the A13 input. This has to be triggered manually. I have been going through the calcx code looking to see if this is implemented - but was interrupted so have not completed that exercise. Using a timer is one way of doing it but not ideal - the ideal solution is to trigger the change when the calculated value input is set.

Will keep looking and post back if I find something.
0
badwolfffAuthor Commented:
Thanks. In any case it works so far. I have tested various scenarios.
0
Julian HansenCommented:
I think I found the answer here
http://www.xsanisty.com/project/calx/

The following question was asked in the discussion at the bottom of the page
what kind of event will be triggered after applying the formula IF($B >0,1,2). I am trying to catch the event fired during the auto calculations.
To which the author responds
Hi ks,

currently on 1.1.9 no custom event will be triggered on calculation, but if you don’t mind you can grab the latest development state on github.

you can trigger event on calculation by add onupdate listener

$('#form').calx({
onupdate : function(data){ /** do your stuff here */ }
});

Open in new window

data will be an object containing all cell with it’s unformatted value, e.g data.A1 = 5.9384

If I understand him correclty you can do the following

$('#sheet').calx({
    onupdate: function(date) {
       $('#guadagnovero').removeClass('showRed');
       if (parseFloat(data.A13) < 0){
           $('#guadagnovero').addClass('showRed');
       }
    }
});

Open in new window


Have not tested the above but give it a go and see if it works.
0
badwolfffAuthor Commented:
Hi I tried this:

$('#sheet').calx({
    onupdate: function(date) {
		window.console&&console.log('form updated');
		$('#guadagno').css({'color':'#666','background-color':'#F0F0F0', 'border':'1px solid #999'});
		if (parseFloat(data.A13) < 0)
		{
			window.console&&console.log('value less than 0');
			$('#guadagno').css({'color':'#fff','background-color':'#F00', 'border':'1px solid #999'});
       }
    }
});				

Open in new window


It doesn't work. You try it yourself since I provided the code. :(
Nothing gets triggered.
0
Julian HansenCommented:
You try it yourself since I provided the code. :(
Sorry code is in a zip and zip files are not generally accepted on EE.

Do you get an error ?
0
badwolfffAuthor Commented:
Hi,
sorry about the zip file. I get nothing. The console log is empty.
I am sending the separate files:
index.htmljquery.numeric.min.jsjquery-calx-2.2.2.min.jsnumeral.min.js

The .js files go in a /script folder.

thanks
0
Julian HansenCommented:
I will take a look - if it does not work the so be it - the author of the plugin seems to think it does but also says there is no support for catching the event - so it is possible it is not supported in which case you are forced to go the timer route.

I wanted to exhaust these options first before suggesting the timer but you found that on your own.

Give me till tomorrow to take a look at source and see what happens with the onupdate.
0
badwolfffAuthor Commented:
Thanks
I remain curious
0
Julian HansenCommented:
Ok I found it

The callback to use is onAfterRender
$('#sheet').calx({
	onAfterRender: function() {
		$('#guadagno').css({'color':'#666','background-color':'#F0F0F0', 'border':'1px solid #999'});
		if (this.getCell('A13').getValue() < 0)
		{
			$('#guadagno').css({'color':'#fff','background-color':'#F00', 'border':'1px solid #999'});
       }
    }
});				

Open in new window

0
badwolfffAuthor Commented:
Hi, thanks. Tried it. Nothing happens. Nothing gets fired in the console either as I put in a couple of alerts.
Shame really! It looked so promising! I even got all excited when I saw it...
0
Julian HansenCommented:
It might be the version of the calx library you are using - I am using the latest one from GitHub
https://raw.githubusercontent.com/xsanisty/jquery-calx/master/jquery-calx-2.2.3.js
Here is my working sample with your code and the above library if you look in the console you will see the event firing

http://www.marcorpsa.com/ee/t682/
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
jQuery

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.