ugrás a tartalomhoz

Js onChange event probléma

halee · 2007. Ápr. 30. (H), 10.38
Sziasztok

Nem nagyon találok megoldást egy olyan problémára, hogy adott három input mező (text típusúak). Az első kettő változásakor a harmadik mező értéke az első kettő összege kell, hogy legyen - ez eddig megy is tökéletsen.
Viszont ilyenkor szükségem lenne arra, hogy az összeg mező onChange metódusa lefusson, mert ez a mező is részösszege egy "subtotal" mezőnek és annak is változnia kéne.

Tehát tulajdonképpen amikor js-ből változtatom a harmadik mező értékét, akkor ott kéne dobni egy hívást a mező onChange eseménykezelőjének, de nem jövök rá, hogy hogyan... ;((

Bocs, ha kicsit összecsapott voltam, de már keresem egy ideje a megoldást.

köszi,
Halee
 
1

Hívd meg!

s_volenszki · 2007. Ápr. 30. (H), 11.27
De ne kávézni! :)

Abból a rutinból ami összeadja az első kettőt, hívd meg a subtotal rutinodat!

Tételezzük fel a három beviteli meződet így:

<input type="text" name="adat1" value="" onChange="Szamolj();" />
<input type="text" name="adat2" value="" onChange="Szamolj();" />
<input type="text" name="adat3" value="" onChange="SzamoljMastIs();" />
javascript

function Szamolj(){
osszeg = document.fromneve.adat1.value + document.fromneve.adat2.value;
document.formneve.adat3.value = osszeg;
SzamoljMastIs();
}

function SzamoljMastIs(){
//Akármi mást is kiszámolok szivesen, tök mindegy higy omChange-re futok le vagy egy másik rutinból hívnak meg!
}
s_volenszki
2

Egy függvény

vbence · 2007. Ápr. 30. (H), 11.46
Én annyival egészíteném ki, hogy egyetlen metódus elég az egész formnak. Szóval MINDEN a szamolj() függvényt hívja, ami MINDEN értéket frissít, amit kell.

Más: az onkeypress talán alkalmasabb lenne (végső esetben setTimeoute-al kombinálva), mert az onchange (legjobb tudsom szerint) csak a fókusz elvesztésekor fut le, tehát 90%ban helytelen adatokat lát a képernyőn a felhazsnáló.
4

onKeyPress-t megnézem

halee · 2007. Ápr. 30. (H), 11.50
Szia,

az onKeyPress jó ötlet és valószínű alkalmazni is fogom, csak az sem oldja meg az a problémát, hogy ha a total1 változik, akkor a subtotal is változzon.

üdv,
Halee
5

namégegyszer

vbence · 2007. Ápr. 30. (H), 12.07
A keypress-t nem is erre javasoltam. Erre az "egyetlen függvényt" (első bekezdés) javasoltam.
3

Ez is lehet megoldás

halee · 2007. Ápr. 30. (H), 11.46
Szia,

Amit írsz az jó, sőt lehet, hogy ez lesz a megoldás. Viszont amivel én most próbálkozom az a kövezkező

<input type="text" name="adat" value="" onChange="Szamolj(this.name,'total1');" />
<input type="text" name="adat" value="" onChange="Szamolj(this.name,'total1');" />
<input type="text" name="adatsum" id="total1" value="" onChange="Szamolj(this.name,'nagytotal');" />
...
<input type="text" name="adatsum" id="total2" value="" onChange="Szamolj(this.name,'nagytotal');" />
...
<input type="text" name="adatsum" id="nagytotal" value=""/>


és a Js meg valami hasonló:
function Szamolj(elemNev,total) {
var c = document.getElementsByName(elemNev);

var ossz=parseInt(0);
for (var i = 0; i < c.length; i++) {
ossz=parseInt(ossz)+parseInt(c[i].value);

}
document.getElementById(total).value=ossz;
        // ...és itt kéne valami ilyen ez persze nem működik ahogy írom
        document.getElementById(total).onChange();
        // ...
}


Bocs, ha van hiba a kódban, most csak gyorsan begépeltem valami hasonlót. Szóval a lényeg, hogy nekem a konkrét mező onChange metódusát kéne meghívnom a paraméterek miatt... ;((

üdv,
Halee
6

onchange(), createEvent()

attlad · 2007. Ápr. 30. (H), 12.34
szükségem lenne arra, hogy az összeg mező onChange metódusa lefusson

Egyszerű mód:
document.getElementById('osszeg').onchange();

Bizonyos esetekben jobb megoldás saját esemény kreálása:
var myEvent = document.createEvent('HTMLEvents');
myEvent.initEvent('change', true, false);
document.getElementById('osszeg').dispatchEvent(myEvent);

Így működik akkor is ha addEventListener-rel csatoltál pl. akár több eseménykezelőt is. Explorer-hez Google: fireEvent vagy createEventObject.
7

példa egyszerűre

toxin · 2007. Ápr. 30. (H), 13.40
az eseményekezelőt closure-ba, így tudod hívni paraméterezve, az eseménykezelő utolsó sorába meghívod a következő eseménykezelőt, összead, szoroz (vagy oszt és kivon), mi kell még :)

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script type="text/javascript">

window.onload = function(){
	
	var operators = {
		add : function (){ for (var i=0,sum=0;i<arguments[0].length;i++) sum += Number(document.getElementById(arguments[0][i]).value); return sum; },
		multiply : function (){ for (var i=0,sum=1;i<arguments[0].length;i++) sum *= Number(document.getElementById(arguments[0][i]).value); return sum; }
	}

	var onLinkedChange = function(source,linked,operator,params){
		source.onchange = function(){
			linked.value = 0;					 
			linked.value = operators[operator || "add"](params);			
			if (typeof linked.onchange != 'undefined') linked.onchange();			
		}
	}
		
	onLinkedChange(document.getElementById('s_1'),document.getElementById('subtotal_1'),'add',['s_1','s_2']);	
	onLinkedChange(document.getElementById('s_2'),document.getElementById('subtotal_1'),'add',['s_1','s_2']);	
	onLinkedChange(document.getElementById('subtotal_1'),document.getElementById('total'),'add',['subtotal_1','subtotal_2']);
	
	onLinkedChange(document.getElementById('s_3'),document.getElementById('subtotal_2'),'multiply',['s_3','s_4']);	
	onLinkedChange(document.getElementById('s_4'),document.getElementById('subtotal_2'),'multiply',['s_3','s_4']);	
	onLinkedChange(document.getElementById('subtotal_2'),document.getElementById('total'),'add',['subtotal_1','subtotal_2']);
	
	
}
</script>
</head>
<body>
<form action="">
	<input id="s_1" type="text" />+
	<input id="s_2" type="text" />=
	<input id="subtotal_1" type="text" disabled="disabled" /><br/>
	
	<input id="s_3" type="text" />*
	<input id="s_4" type="text" />=
	<input id="subtotal_2" type="text" disabled="disabled"/>+=
	
	<input id="total" type="text" disabled="disabled"/>
</form>

</body>
</html>

üdv t

jav: és refaktorizálás után :))

window.onload = function(){
	
	var $ = function(id) {return document.getElementById(id)};	
	
	var onLinkedChange = function(linkedElement,opr,oprnds){
		
		var operators = {
			add : function (){ for (var i=0,sum=0;i<arguments[0].length;i++) sum += Number(document.getElementById(arguments[0][i]).value); return sum; },
			multiply : function (){ for (var i=0,sum=1;i<arguments[0].length;i++) sum *= Number(document.getElementById(arguments[0][i]).value); return sum; }
		}
		
		var onLinkedChangeDo = function(event){
			this.value = 0;					 
			this.value = operators[opr || "add"](oprnds);			
			if (typeof this.onchange != 'undefined') this.onchange();			
		};
				
		return function(event) { onLinkedChangeDo.call($(linkedElement),event) };
	}
	
	// linkedElement,operator,operandus		
	$('s_1').onchange = onLinkedChange('subtotal_1','add',['s_1','s_2']);
	$('s_2').onchange = onLinkedChange('subtotal_1','add',['s_1','s_2']);
	
	$('s_3').onchange = onLinkedChange('subtotal_2','multiply',['s_3','s_4']);
	$('s_4').onchange = onLinkedChange('subtotal_2','multiply',['s_3','s_4']);
	
	$('subtotal_1').onchange = onLinkedChange('total','add',['subtotal_1','subtotal_2']);
	$('subtotal_2').onchange = onLinkedChange('total','add',['subtotal_1','subtotal_2']);
}
8

Köszi

halee · 2007. Ápr. 30. (H), 21.06
Szia,

Köszi a választ, valószínű, hogy hasonló lesz a megoldás...

üdv,
Halee
9

Még egy probléma

halee · 2007. Május. 9. (Sze), 10.52
Sziasztok!

Toxin megoldásához hasonlót próbálok alkalmazni, viszont egy újabb problémába ütköztem. Amikor egy mező értéke változik tehát onChange fgv lefut, akkor több számolást is kéne egyszerre végeznem, tehát több különböző paraméterű onLinkedChange fgv-t kéne futtatnom.

Eddig nem igazán sikerült erre megoldást találni (próbáltam egy fgv-t definiálni és abból meghívni, de akkor meg mintha az event-t nem kapná meg a onLinkedChange)... ;(

köszi,
Halee
10

De mostmár tényleg...

vbence · 2007. Május. 9. (Sze), 11.33
... érdekelne, miért nem EGY függvénybe vonod össze az egész számolást?
11

...

halee · 2007. Május. 9. (Sze), 11.48
- Mert több művelet futna le (ez mondjuk nem jelentős, mert kliens oldalon fut)

- Mert úgy működik a form, hogy ha egy input text elől kiveszel egy jelölő négyzetet, akkor annak változása nem befolyásolhatja többé a form többi mezőjét (akkor sem, ha egy másik érték számításához erre a mezőre szükség lenne) és ez eléggé megbonyolítaná az egy fgv-ben való kezelést, mivel egy kb 120-130 mezős formról van szó.

- Mert jobban tetszik ez a megoldás... ;))

Egyébként egy dolgon már elgondolkoztam, ha már egy függvényes megoldás lesz, akkor az bizony meg át szerver-oldalra és akkor csak a tényleges felhasználói input mezők lesznek a képernyőn, de a második pontban leírt problémát akkor is fel kell majd oldani valahogy...

üdv,
Halee
12

ciklus?

vbence · 2007. Május. 9. (Sze), 13.38
Ajánlom figyelmedbe... csodákat művel még 120-130 mező esetén is :)

A pipás dolgot nem értem, de ha módosítasz egy másik mezőt ami szintén befolyásolja a pipás összegét, akkor szükséged van a pipás mező eredeti értékére, amit tárolsz valahol. Vagy ha nem kell résztvennie ez összegben, akkor meg semmilyen pluszmunkát nem jelent (csak egy IF-et).

De ahogy gondolod..