Avatar billede razmuz_dk Nybegynder
07. april 2005 - 16:20 Der er 23 kommentarer og
1 løsning

Tekstfelter tømmes "af sig selv"?

Hejsa JS-Eksperter,

Jeg er ved at lave en webside, der kan holde styr på fakturaer mm. I den forbindelse har jeg følgende java script:
        <script type="text/javascript">
            <!--
            line_id=1;
            function calculatelinetotal(line_id) {
                document.getElementById('Total['+line_id+']').value = document.getElementById('Antal['+line_id+']').value*document.getElementById('LinjeBelob['+line_id+']').value;
            }
            function addline(FakturaUdstederVareNavn,KundeVareNr,EnhedsBetegnelse,DimensionsKontoStreng2,Antal,LinjeBelob,LinjeBelobMoms) {
                if(FakturaUdstederVareNavn === undefined) FakturaUdstederVareNavn='';
                if(KundeVareNr === undefined) KundeVareNr='';
                if(EnhedsBetegnelse === undefined) EnhedsBetegnelse='';
                if(DimensionsKontoStreng2 === undefined) DimensionsKontoStreng2='';
                if(Antal === undefined) Antal='0';
                if(LinjeBelob === undefined) LinjeBelob='0';
                linje = '<div id="line_'+line_id+'">';
                    linje += '<table style="width: 100%;">';
                        linje += '<tr>'
                            linje += '<td style="width: 20%;"><input name="beskrivelse['+line_id+']" size="30" value="'+FakturaUdstederVareNavn+'" /></td>';
                            linje += '<td style="width: 10%;"><input name="KundeVareNr['+line_id+']" size="14" value="'+KundeVareNr+'" /></td>';
                            linje += '<td style="width: 10%;"><input name="EnhedsBetegnelse['+line_id+']" size="14" value="'+EnhedsBetegnelse+'" /></td>';
                            linje += '<td style="width: 20%;">[Afgifter] - TOM PT.</td>';
                            linje += '<td style="width: 10%;"><input name="DimensionsKontoStreng2['+line_id+']" size="14" value="'+DimensionsKontoStreng2+'" /></td>';
                            linje += '<td style="width: 5%;"><input id="Antal['+line_id+']" name="Antal['+line_id+']" size="5" value="'+Antal+'" onchange="calculatelinetotal('+line_id+');" /></td>';
                            linje += '<td style="width: 5%;"><input id="LinjeBelob['+line_id+']" name="LinjeBelob['+line_id+']" size="5" value="'+LinjeBelob+'" onchange="calculatelinetotal('+line_id+');" /></td>';
                            linje += '<td style="width: 5%;"><input type="checkbox" name="LinjeBelobMoms['+line_id+']" '; if(LinjeBelobMoms) linje += ' checked'; linje += ' /></td>';
                            linje += '<td style="width: 5%;"><input id="Total['+line_id+']" name="Total['+line_id+']" size="5" /></td>';
                            linje += '<td style="width: 10%;"><input type="button" onclick="deleteline('+line_id+');" value="Slet linje" /></td>';
                        linje += '</tr>';
                    linje += '</table>';
                linje += '</div>';
                document.getElementById('linjer').innerHTML = document.getElementById('linjer').innerHTML+linje;
                calculatelinetotal(line_id);
                line_id++;
            }
            function deleteline(line_id) {
                document.getElementById('line_'+line_id).innerHTML = '';
//                document.getElementById('line_'+line_id).outerHTML = ''; // virker ikk!?
            }
            // -->
        </script>


Scriptet styrer når man trykker på tilføj (add) og slet (delete) fakturalinje på den side hvor man kan redigere/oprette fakturaer. Men den opfører sig mærkeligt, når man gør følgende.

Man trykker først på Tilføj linje (addline()) og der kommer en linje frem. Man udfylder nogle af felterne i denne linje. Når man så trykker på addline() igen, så tømmes felterne i den første linje?! - Det forstår jeg ikke... har forsøgt at "troubleshoote" så meget som jeg kan, men kan ikke finde fejlen.

Help! :)

mvh. Rasmus
Avatar billede razmuz_dk Nybegynder
07. april 2005 - 16:24 #1
Jeg har lige fundet ud af at det virker i Internet Explorer.. hmm ? :S
Avatar billede barklund Nybegynder
07. april 2005 - 16:25 #2
Har du et link - så er det lidt nemmere at teste?
Avatar billede razmuz_dk Nybegynder
07. april 2005 - 16:33 #3
I får lige en statisk version af siden.. :)
http://faktura.epaper.dk/statisk.html
Avatar billede barklund Nybegynder
07. april 2005 - 16:37 #4
Ah, nu forstår jeg det vist godt. I det du skriver:

document.getElementById('linjer').innerHTML = document.getElementById('linjer').innerHTML+linje;

Så tilføjer du faktisk hele den gamle html en gang til - altså du sletter alt hvad der står og overskriver det med noget nyt - hvoraf noget af det svarer til det gamle.

Prøv at bruge document.getElementById('linjer').appendChild i stedet - måske bare direkte, måske skal din div være et rigtigt element først :)
Avatar billede razmuz_dk Nybegynder
07. april 2005 - 16:41 #5
Arh okay.. Men jeg forstår ikke helt hvad det er du foreslår.

Hvordan virker appendChild? Jeg forsøgte lige med
document.getElementById('linjer').appendChild = document.getElementById('linjer').appendChild+linje;

Så skete der ingenting.. og hvad vil det sige at min div skal være et rigtigt element? ... :)
Avatar billede barklund Nybegynder
07. april 2005 - 16:43 #6
appendChild er en funktion - prøv med:

document.getElementById('linjer').appendChild(linje);
Avatar billede razmuz_dk Nybegynder
07. april 2005 - 16:47 #7
Virker ikke .. Firefox siger: Error: uncaught exception: [Exception... "Could not convert JavaScript argument arg 0 [nsIDOMHTMLDivElement.appendChild]"  nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)"  location: "JS frame :: http://faktura.epaper.dk/interface.php?action=dokumenter&subaction=editor :: addline :: line 78"  data: no]
Avatar billede olebole Juniormester
07. april 2005 - 16:55 #8
<ole>

appendChild er en metode, der hører til ECMA-DOM bindingerne - og den kan ikke bruges med en HTML-streng. Typisk bruges den som følger:

function addSpan(elm) {
  var txt, sp = document.createElement("span");
  sp.style.color = "red";
  elm.appendChild(sp);
  txt = document.createTextNode("En test af en slags ...");
  sp.appendChild(txt);
}

<div onclick="addSpan(this)">Klik her</div>

/mvh
</bole>
Avatar billede razmuz_dk Nybegynder
07. april 2005 - 16:55 #9
Kan du/I evt. komme på et alternativ for hvordan dette kan laves? Det skal helst foregå via javascript (altså uden man skal til at reloade siden)...
Avatar billede olebole Juniormester
07. april 2005 - 16:58 #10
Tjooo ... mon ikke du kunne bruge dette:

function deleteline(line_id) {
    var elm = document.getElementById('line_'+line_id);
    elm.parentNode.removeChild(elm);
}
Avatar billede razmuz_dk Nybegynder
07. april 2005 - 17:00 #11
olebole -> Du må have læst min "virker ikk"-kommentar i js-koden? hehe det var faktisk ikke det jeg spurgte om :) men tak da :)

Problemet er at tekstfelterne som er indsat via innerHTML tømmes hvergang man tilføjer ny linje via addline!
Avatar billede olebole Juniormester
07. april 2005 - 17:10 #12
Problemet er, at du altid vil overskrive dit 'linjer'-div med 'friske' input-felter, når du bruger innerHTML. Ved du i øvrigt, man slet ikke kan bruge innerHTML under XHTML?

Skal du tilføje linier uden at tømme felter, skal du bruge DOM på samme måde, so jeg viste i (07/04-2005 16:55:37). Du opretter elementer med:
  elm = document.createElement("TAG_NAVN")
- tekst med:
  txt = document.createTextNode("Tekst");
- styler et element med:
  elm.style.color = "red"
- sætter attributter med:
  elm.setAttribute("colSpan", 3)
- tilføjer en node til en anden med:
  elm.appendChild(txt)
Avatar billede olebole Juniormester
07. april 2005 - 17:23 #13
Nu er der jo tale om en forholdsvis kompleks struktur, du skal lave - og så kan følgende fremgangsmåde ofte være en fordel:

<script type="text/JavaScript">
function addElm(from, to) {
    var node;
    from = document.getElementById(from);
    to = document.getElementById(to);
    node = from.cloneNode(true); // true gør, at childnodes også klones
    node.getElementsByTagName("input")[0].setAttribute("name", "hest_input_et_eller_andet");
    to.appendChild(node);
}
</script>

<button onclick="addElm('hest', 'gnu', 'nummer_1')">TEST</button>

<div id="gnu">En tekst i div'et gnu</div>

<!-- Templates - START -->
<div style="display:none">
    <div id="hest">En test i div'et hest <input type="text" onclick="alert(this.name)"></div>
</div>
<!-- Templates - END -->

- prøv at kikke lidt på det og sammenlign med det andet DOM-eksempel, jeg skrev ... så siger det meste nok sig selv  :)
Avatar billede razmuz_dk Nybegynder
07. april 2005 - 17:25 #14
Nej det vidste jeg ikke at man ikke kunne.

Okay, dvs. "man" bruger simpelthen ikke det med at sætte html-koder ind via js?

Og hvis du/I vil være så venlig, hvad er en node i denne sammenhæng? Gerne med eksempel, tak.
Avatar billede razmuz_dk Nybegynder
07. april 2005 - 17:27 #15
Okay, jeg kigger lige på det og så vender jeg tilbage en af dagene.
Avatar billede olebole Juniormester
07. april 2005 - 17:39 #16
Nej, hvis du bruger ting som 'innerHTML', 'document.forms' eller 'document.images', kan browseren ikke tolke koden som XHTML og HTML-parseren tager i stedet over.
Det betyder at koden så bliver parsed som fejlfyldt, da DTD'en så er forkert i forhold til indholdet - samtidig med, at alle dine ' />' ikke er tilladt i HTML og skal rettes af browseren, før dokumentet kan tolkes og vises.

Nu betyder det nok ikke så meget, da din XHTML-kode efter al sandsynlighed i forvejen parses som dårlig HTML. XHTML er stort set ubrugeligt, som WWW er idag ... prøv at læse:
  http://www.eksperten.dk/artikler/537
  http://www.eksperten.dk/artikler/538
Avatar billede razmuz_dk Nybegynder
08. april 2005 - 12:49 #17
Hej igen, ja jeg har læst dine fremragende artikler... eller rettere skimmet dem - men vil helst sikkert læse dem når tiden bliver til det.

Er det bare mig eller udføres DOM-funktionerne (?? - eller hvad man skal kalde dem) hurtigere end innerHTML? Det "føles" sådan.. :)
Avatar billede olebole Juniormester
08. april 2005 - 16:48 #18
Tak for rosen  :)
Ja, det er som oftest bedre performende, når man manipulerer dokumentet med DOM fremfor innerHTML. Til gengæld kan det fylde en bunke og tage tid at skrive, hvis man opretter hvert element og node for sig.

'Template' metoden, hvor man kloner et HTML-element, er på den anden side fantastisk overskuelig og let at arbejde med. Jeg anvender den selv en hel del - og kan absolut anbefale den. Faktisk har jeg ikke testet lige den metodes hurtighed, men den indebærer så væsentlige fordele, at de i sig selv afgør mit valg.
Den dag - Fanden forbyde, den måtte komme - hvor jeg dynamisk skal skrive 1000 tabeller under hinanden, foretager jeg måske en test  :)
Avatar billede razmuz_dk Nybegynder
10. april 2005 - 16:52 #19
Hvordan virker template-metoden? Og hvad er det? :S Hvis du vil være så venlig at forklare...
Avatar billede olebole Juniormester
10. april 2005 - 17:16 #20
Det viste jeg dig i (07/04-2005 17:23:13)
Avatar billede razmuz_dk Nybegynder
17. april 2005 - 15:00 #21
Olebole (10/04-2005 17:16:52) -> Dvs. DOM og "template-metoden" er "det samme"?

Uanset hvad, tak for al hjælpen begge to. Det appendChild-halløj er fedt :) Det vil jeg bruge fremover!... Gider I begge smide et svar?:)
Avatar billede razmuz_dk Nybegynder
25. april 2005 - 10:24 #22
.. ingen svar?
Avatar billede barklund Nybegynder
25. april 2005 - 10:35 #23
Jeg kan da godt - selvom det er olebole, der ved noget om noget :)
Avatar billede razmuz_dk Nybegynder
30. april 2005 - 18:58 #24
hm, han vil ik' lægge svar...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester