Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: JS: Muuttujien siirtäminen framesta pääsivulle

Sivun loppuun

kalajolli [27.03.2013 14:59:23]

#

Hei, osaisiko täällä joku sanoa, onko mahdollista siirtää muuttujien arvoja html sivusta toiseen?

Itselläni on kolme html sivua joilla jokaisella on kaavake, jokaisen kaavakkeen vastauksista riippuen lasketaan hinta tuotteelle. Tämä hinta lähetetään ns pääsivulle jossa näiden kaikkien kolmen kaavakkeen hinta lasketaan yhteen.

Ongelmana on, miten tuo tiedonsiirto saataisiin tapahtumaan? Käytettävissä on myös PHP

groovyb [27.03.2013 15:00:49]

#

Query string?

kalajolli [27.03.2013 15:02:08]

#

Niin, jokainen kaavake on siis pääsivuun upotettuna iframena.

Käytännössä siis on sivu, jossa asiakas voi lisätä 'koriinsa' tuotteita, tämän tuotteen hinta lasketaan kaavakkeen avulla (materiaali, mitat, yms)... kaavake on itsessään suhteellisen monimutkainen kokonaisuus, jonka generointiin käytän Jqueryä. Käyttäjän lisätessään uuden tuotteen 'koriinsa' luodaan uusi divi jonka sisällä on tuo sama kaavake. Koko kaavake yhdistelmä kuitenkin kosahtaa heti uuden tuotteen lisäämisen jälkeen, koska kaavakkeen kentillä on samat id tunnukset. Tämän eliminoidakseni olen upottanut ne omiin iframeihinsa, mutta nyt ongelmana on tiedon siirtäminen sivusta toiseen.

Voi myös ehdottaa toisenlaista ratkaisua, mutta kaikkien kenttien muuttujien nimen vaihtaminen tulee suhteellisen hankalaksi. Mukana on myös ajaxia jolloin hinta päivittyy automaattisesti kaavaketta täyttäessä.

samip [27.03.2013 15:05:59]

#

eväste

kalajolli [27.03.2013 15:16:24]

#

Miten tuo evästeen tekeminen käytännössä tapahtuu? Yritin hyödyntää sessionia sivussani, mutta senkin kanssa meni sormi suuhun.

Metabolix [27.03.2013 15:17:07]

#

Siis kyllähän oman sivuston sisäisistä iframeista voi hakea tietoa ihan suoraan, tai iframe voi välittää tietoja ylöspäin.

// Ikkunan (sivun) oma muuttuja:
window.muuttuja = "hei";
// Isäntäikkunan muuttuja:
window.parent.muuttuja = "hoi";
// Sivulla olevan framen muuttuja:
document.getElementById("framen-id").contentWindow.muuttuja = "hyi";

Sinänsä miettisin tuossa, onko mitään järkeä tehdä useaa iframea, kun voisi vain tehdä yhden toimivan sivun.

(Edit: Lisätty puuttuva contentWindow.)

kalajolli [27.03.2013 15:27:00]

#

No ei ole välttämättä järkeä tehä noita Iframeja, mutta kuten sanoin ongelmana on kun tuo interaktiivinen kaavake räjähtää kun kaavakkeesta haetaan tietoja ja niitä on sivulla useampia.

esimerkiksi

muoto = $('input[name=tuotteenmuoto]:checked', '#tuotelaskenta').val();

ei jokaista yksittäistä elementtiä jaksaisi nimetä erikseen aina kun uusi tuote lisätään koriin.

Metabolix [27.03.2013 15:51:18]

#

Lisäsin esimerkkiin puuttuvan contentWindow-sanan.

kalajolli kirjoitti:

Ongelmana on kun tuo interaktiivinen kaavake räjähtää kun kaavakkeesta haetaan tietoja ja niitä on sivulla useampia.

Ei ole mikään ongelma käsitellä monirivistä lomaketta, enkä näe, miten iframet olennaisesti auttaisivat asiassa.

Monirivisen lomakkeen käsittelyssä ovat hyödyllisiä jQueryn funktiot parents, jolla saa elementin puusta ylempää ($(input).parents("tr.tuote")), ja find, jolla saa valitun elementin lapsielementtejä ($(tr).find("input.hinta")). Tässä touhussa on myös helpompi käyttää luokkia eikä nimiä.

PHP:lle lähettämistä taas helpottaa, jos kenttien nimissä käyttää hakasulkuja (data[1][määrä]), jolloin koko lomakkeen saa PHP:lle yhtenä taulukkona, jossa vieläpä jokainen lomakkeen rivi on erikseen.

kalajolli [27.03.2013 16:02:37]

#

Niin tarkoitin siis, että kun samoja kaavakkeita on sivulla useampia, niin sivu ei tiedä mistä kaavakkeesta tietoja haetaan, enkä tiedä onko edes kannattavaa luoda jokainen kaavake omin kenttätunnuksin, sillä silloin systeemi menee suhteellisen sekavaksi.

luokat javaScriptissa... Eipä ole niistäkään viellä kokemusta :D

mitäs sanot onko tuollaisen generoitavan kaavakkeen tekeminen tähän tyyliin edes kannattavaa

 var mitatotsikko ='<h1>Syötä mitat</h1>';

	var syvyys = '<input type="number" name="syvyys" value="0">cm - Syvyys</input><br \>';
	var alasyvyys = '<input type="number" id="alasyvyys" value="0">cm - Alasyvyys</input><br \>';
	var leveys = '<input type="number" id="leveys" value="0">cm - Leveys</input><br \>';

if( muoto == "r1")
  $('#div_mitat').html(mitatotsikko + syvyys);

  if( muoto == "r2")
  $('#div_mitat').html(mitatotsikko + alasyvyys + leveys + syvyys);

Metabolix [27.03.2013 16:06:38]

#

kalajolli kirjoitti:

luokat javaScriptissa... Eipä ole niistäkään viellä kokemusta :D

Tarkoitin ihan HTML:n class-attribuuttia, kuten voisi päätellä siitä, että käytin luokkavalitsimia esimerkissäni ja mainitsin sen vaihtoehtona nimille (name-attribuutille).

kalajolli kirjoitti:

mitäs sanot onko tuollaisen generoitavan kaavakkeen tekeminen tähän tyyliin edes kannattavaa

En ota kantaa koodisi laatuun tai tarkoitukseen, mutta kyllä joskus kaavakkeita on käytännöllistä generoida JS:llä. Toisaalta jos kaavake ei muutu sivun latautumisen jälkeen, voisit generoida sen PHP:llä.

kalajolli [27.03.2013 16:09:52]

#

Niin tarkoitin siis, että kun samoja kaavakkeita on sivulla useampia, niin sivu ei tiedä mistä kaavakkeesta tietoja haetaan, enkä tiedä onko edes kannattavaa luoda jokainen kaavake omin kenttätunnuksin, sillä silloin systeemi menee suhteellisen sekavaksi.

Metabolix [27.03.2013 16:21:58]

#

En ymmärrä edelleenkään ongelmaasi. Monen lomakkeen käyttö on aivan yksinkertaista.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script>
$(function() {
	$("form button.laske").click(function(e) {
		e.preventDefault();
		var form = $(this.form);
		var x = form.find("input.x").val();
		var y = form.find("input.y").val();
		form.find("input.z").val((+x) + (+y));
	});
});
</script>
<form>
	<input class="x" /> +
	<input class="y" />
	<button class="laske">=</button>
	<input class="z" />
</form>
<form>
	<input class="x" /> +
	<input class="y" />
	<button class="laske">=</button>
	<input class="z" />
</form>

kalajolli [27.03.2013 16:28:53]

#

Tuo näyttää hyvältä, ongelma siis on kun käyttäjä lisää uuden tuotteen, lisää hän uuden kaavakkeen joka on suora kopio toisesta kaavakkeesta, mukaanlukien ID't ynnämuut.

Niin ja tuo laskenta tapahtuu realiaikaisesti ajaxilla, ilman erillistä Laske nappia

Mutta suurkiitokset tuosta Iframen muuttujiin käsiksipääsy neuvosta, tuo contentWindow juttu palauttaa kyllä muuttujan lisäksi myös saman ID nimen omaavan divin html sisällön

Metabolix [27.03.2013 17:29:44]

#

kalajolli kirjoitti:

Tuo näyttää hyvältä, ongelma siis on kun käyttäjä lisää uuden tuotteen, lisää hän uuden kaavakkeen joka on suora kopio toisesta kaavakkeesta, mukaanlukien ID't ynnämuut.

Kuten näet, koodissani ei ole yhtään id:tä. Ongelmasi on siis itse aiheutettu. Tee sivu kunnolla, niin se toimii kunnolla, eipä voi muuta sanoa. Jos selittäisit kunnolla edes, mitä sivun suunnilleen on tarkoitus tehdä, voisi ehkä antaa tarkempia neuvoja. Nappien käyttö ei ole mitenkään edellytys monelle lomakkeelle tai moniriviselle lomakkeelle.

kalajolli kirjoitti:

saman ID nimen

HTML-sivulla ei saa koskaan olla kahta samaa id:tä, eli taas on oma syysi, jos koodi ei toimi.

kalajolli [27.03.2013 19:58:26]

#

Juu, web ohjelmointi ei kyllä ole sitä mitä olen opiskellut, mutta toimeksiannon vuoksi sitäkin joutuu nyt harjoittelemaan.

Eli, sivustolla on nappi jolla käyttäjä voi lisätä uuden tuotteen koriinsa. Tämä nappi lisää myös sivulle divin johon ladataan jQueryn .load("kaavake.html") komennolla uusi kaavake, jonka vastauksista riippuen lasketaan hinta kyseiselle tuotteelle, kaavake on interaktiivinen, sen kentät muuttuvat valinnoista riippuen. Esim tuotteen mallista riippuen vaihtuu sen vaatimat mitta-syöte kentät. Kaavake on yhteydessä palvelinpuolen PHP tiedostoon ajaxin avulla, jossa on laskentakaaviot hinnalle, mitoista riipuvat materiaalikustannuskset yms. jotka palautuu käyttäjän näkyville heti kaavaketta täyttäessään.

Itse pääsivulla sitten lasketaan kaikkien lisättyjen tuotteiden yhteenlaskettu hinta.

Upotan nämä generoidut kaavakkeet Iframeen sen takia, kun muutoin kaavakkeet sekoittavat toisensa (samat ID't jota ei tietenkään saisi olla), enkä ole tämän eteen muuta keksinyt. Tuo sun antama koodivinkki olisi ilmeisesti vastaus tähän, mutten täysin ymmärrä sen syntaksia. javaScript ja JQuery ovat ennestään minulle täysin vieraita

kalajolli [02.04.2013 09:36:35]

#

Kiitos metabolix tuosta koodivinkistä, helpotti työskentelyä huomattavati! Viellä jäi kuitenkin hiukan epäselväksi tuo

Metabolix kirjoitti:

PHP:lle lähettämistä taas helpottaa, jos kenttien nimissä käyttää hakasulkuja (data[1][määrä]), jolloin koko lomakkeen saa PHP:lle yhtenä taulukkona, jossa vieläpä jokainen lomakkeen rivi on erikseen.

Miten se käytännössä tapahtuu

Metabolix [02.04.2013 15:07:40]

#

En tiedä, mikä sinulle on "käytännössä", mutta ei se tämän kummempaa ole:

<input name="data[1][nimi]" type="text" />
<input name="data[1][maara]" type="text" />

<input name="data[2][nimi]" type="text" />
<input name="data[2][maara]" type="text" />
<?php
// $_POST["data"] = array("1" => array("nimi" => "x", ...), "2" => ...);
foreach ($_POST["data"] as $rivi) {
	$nimi = $rivi["nimi"];
	$maara = $rivi["maara"];
	echo htmlspecialchars("{$maara} × {$nimi}<br />\n");
}

kalajolli [02.04.2013 15:49:34]

#

Juuri tuota tarkoitin!

Juu, siis luodaan lista josta voidaan hakea halutusta alkiosta arvo, miten tuollaisen taulukon siirtäminen phplle onnistuu? Koska tieto siirretään taulukkona niin ei varmaankaan tarvitse huolehtia taulukon koosta tai kenttien nimistä erikseen?

kutakuinkin näin?

$.ajax({
  url: "laskenta.php",
  data: { 'data[]' : data },
  type: 'post',
  success: function(data) {
    alert(data);
  }

Metabolix [02.04.2013 16:14:05]

#

jQuery ei käsittele taulukoita tuolla tavalla, vaan kentät pitää luetella yksitellen (kaikkine hakasulkuineen). Kuitenkin helpoiten saat koko lomakkeen tiedot jQueryn serialize-funktiolla:

var lomake = $("#lomakkeen_id"); // tms.
$.ajax({
	data: lomake.serialize()
});

kalajolli [02.04.2013 16:21:39]

#

Tuo serialize() auttaa tässä hommassa kyllä ihan uskomattoman paljon... Kiva kun mitään tuollaisia ei ole ennestään tiedossa :D

Lebe80 [03.04.2013 00:14:23]

#

kalajolli kirjoitti:

Tuo serialize() auttaa tässä hommassa kyllä ihan uskomattoman paljon... Kiva kun mitään tuollaisia ei ole ennestään tiedossa :D

Niin, siinähän olisi pitänyt omatoimisesti vähän tutkia asioita, jotta tuommoisen tietäisi ;)

kalajolli [03.04.2013 09:39:39]

#

Omatoimisesti tässä on kyllä tutustuttu koko JS ja JQuery viimeisen kuukauden aikana, ei vain kykene kaikkea sisäistämään heti.

kalajolli [12.04.2013 15:18:24]

#

Nyt tuli eteen sellainen ongelma, että taas pakko kysyä täältä.

Olen perehtynyt nyt tuohon JQueryn validate pluginiin ja ongelmana on etten saa asetettua .validate() funtion kutsuun this operaattoria millään. Koska olen tehnyt formit nyt Metabolixin ohjeen mukaan, ei formeilla ole omaa ID tunnusta.

Kuitenkin, koska sivulla on useampi formi, täytyisin funktion kutsuun jotenkin saada sisään mitä formia yritetään validoida.

käytännössä siis jotenkin näin:

$(button.validate).click(function (){
  $(this.form).validate();
});

Tuo kuitenkin palauttaa virhekoodin "Uncaught TypeError: Object [object Object] has no method 'validate'"

Olen myös yrittänyt tehdä funktion jota kutsutaan nappia painamalla, funktio saa sisäänsä formin jossa kyseinen nappi on. Tämä palauttaa saman virhekoodin.

function validate(targetform){

    $(targetform).validate({
            errorPlacement: function (error, element) {
            error.appendTo( element.parent("div").next("div"));
             }
       });
    }

Metabolix [12.04.2013 19:51:19]

#

Ensimmäisen koodisi virhe on siinä, että "button.validate" tarvitsee lainausmerkit. Muutenhan yrität syöttää $-funktiolle button-nimisen objektin validate-ominaisuuden arvon, vaikka tarkoitus on syöttää $-funktiolle teksti "button.validate". Kannattaa aina katsoa, mihin koodiriviin virheilmoitukset viittaavat. (Itse en usein lue varsinaista ilmoitusta ollenkaan vaan katson pelkästään rivinumeron.)

kalajolli [15.04.2013 08:32:30]

#

No ei ollut kaukana :D kumma juttu etten tajunnut tuota itse kokeilla, kiitos avusta! Rupesi heti toimimaan :)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta