Avatar billede lsskaarup Nybegynder
28. december 2010 - 13:53 Der er 22 kommentarer og
1 løsning

Hjælp til opbygning af noget lignede named anchors

Jeg har en side bestående af en masse felter indlejret i næsten lige så mange <ul> o.l. Disse felter kan brugeren indtaste værdier i, og ved tryk på enter, bliver en processide kaldt, via en submitknap. Processiden sørger for at gemme data i en database, og indlæse frontend'en igen.

Mit problem er at vi gerne skal have <ul> til at være lukket fra starten af, men at den <ul> som man sidst indtastede noget i er åben, og at fokus samtidig ligger på det sidst indtastede felt. Altså noget med named anchors, men jeg kan ikke lige greje, hvordan jeg løser det, når jeg springer over flere sider, og at submitknappen samtidig er den seneste aktive element, hvilket den jo bliver ved tryk på enter.

Håber nogen kan hjælpe.
Avatar billede lsskaarup Nybegynder
28. december 2010 - 13:57 #1
Et lille udpluk af koden.

<form action="/entreprise_ordre_process.php" method="post" name="ds" id="ds" style="display:inline;" autocomplete="off" onsubmit="fang_felt(document.activeElement)">
<input type="hidden" name="nextpage" value="14">
<input type="hidden" name="thispage" value="13">
<input type="hidden" name="ordreid" value="<?php echo $_GET['id']; ?>">
<input type="hidden" name="låser" value="<?php echo $personid;?>"/>
<input type="hidden" name="låser_ini" value="<?php echo $select;?>"/>
<table border="0" width="1080px">
<input type="submit" name="gem" class="submit" value="Gem" style="position: absolute; left: -200px; top: -200px;"/>

<li>
        <a href="#" onclick="showhide('id_kontrakt');" style="width:335px;">
            Kontraktarbejder
        </a>

      <?php echo "<input name='overskrifter[]' type='text' class='listformsmallx' readonly style='text-align:right;font-weight:bold' value='" . number_format($position_sum_pris, 0, ',', '.') ."' /> ";?>
      <img src="/gfx/transparent.gif" style="width:100px;height:5px;" />
       
      <?php for ($q=0;$q<count($position_udført_pris);$q++) {
            echo "<input name='overskrifter[]' type='text' class='listformsmallx' readonly style='text-align:right;font-weight:bold' value='" . number_format($position_udført_pris[$q], 0, ',', '.') ."' /> ";
        }?>
       
    </li>
    <?php
    $tæller = 0;
   
    $query = "SELECT * FROM aconto_plan WHERE ordre_id = '".$_GET['id']."' AND type = 1 ORDER BY id ASC";
    $query_ud = mysql_query($query) or die(mysql_error);?>

    <div id="id_kontrakt" style="display:block;">

        <?php
        if (!mysql_num_rows($query_ud) || !isset($query_ud)) {
            $tæller++;?>
        <ul>
                <input name="p_id[]" type="hidden" class="inputextrasmall" />
                <input name="p_navn[]" type="text" class="inputextrasmall" />
                <img src="/gfx/transparent.gif" style="width:100px;height:5px;" />
                <!--<input name="p_dato[]" type="text" class="inputextrasmall" />-->
                <input name="p_emne[]" type="text" class="inputextrasmall" />
                <input name="p_belob[]" type="text" class="inputextrasmall" />
        </ul>
        <?php } else {
            while ($position = mysql_fetch_array($query_ud)) {?>
                <ul>
                    <?php $tæller++;
                   
                    $forespøgz = "SELECT *, ab.låst AS ab_låst, a.id AS id, ab.id AS ab_id FROM aconto_plan AS a
                                LEFT JOIN aconto_kolonner AS ak ON a.id = ak.acontoplan_id
                                LEFT JOIN aconto_beløb AS ab ON ab.acontokolonner_id = ak.id
                                WHERE a.ordre_id = '".addslashes($_GET['id'])."' AND a.id = '".$position['id']."' AND type = 1";
                                //ORDER BY `ab`.`acontokolonner_id` DESC ";
                                               
                    $forez = mysql_query($forespøgz) or die(mysql_error);
                    $counterz=1;
                    $arz = mysql_num_rows($forez);?>
                    <input name="p_id[]" type="hidden" class="inputextrasmall" value="<?php echo $position['id'];?>"/>
                    <input name="p_navn[]" type="text" class="inputextrasmall" value="<?php echo $position['navn'];?>"//>
                    <img src="/gfx/transparent.gif" style="width:100px;height:5px;" />
                    <!--<input name="p_dato[]" type="text" class="inputextrasmall" />-->
                    <input name="p_emne[]" type="text" class="inputextrasmall" value="<?php echo $position['emne'];?>"//>
                    <input id="beløb[<?php echo $tæller;?>]" name="p_belob[]" type="text" class="inputextrasmall" value="<?php echo number_format($position['belob'], 0, ',', '.');?>" style="text-align:right"/>
                 
                      <?php
                    while ($foresz = mysql_fetch_array($forez)) {
                        if ($foresz['kolonnenr'] == 0) {// || !isset($foresz['kolonnenr'])){
                            $foresz['kolonnenr'] = 1;
                        }
                       
                        if ($foresz['ab_id'] == 0 ) {//|| !isset($foresz['kp_id'])){
                            $foresz['ab_id'] = 0;
                        }
                       
                        if ($counterz == 1) {?>
                            <input id="<?php echo $tæller;?>" name="p_udfort_procent[]" type="text" class="inputextrasmall" onchange="beregn_udført_beløb(this, <?php echo $arz;?>);" value="<?php echo number_format($foresz['aktuel_procent'], 0, ',', '.');?>" style="text-align:right"/>
                        <?php } ?>
                 
                        <input id="ub[<?php echo $tæller;?>][<?php echo $foresz['kolonnenr'];?>]" name="p_udfort_belob[<?php echo $foresz['id'];?>][<?php echo $foresz['kolonnenr'];?>][<?php echo $foresz['ab_id'];?>]" type="text" class="inputextrasmall" value="<?php echo number_format($foresz['beløb'], 0, ',', '.');?>" <?php if ($foresz['ab_låst'] != "1") { echo "class='inputextrasmallx'"; } else { echo "class='listformsmallz' readonly";}?> style="text-align:right;"/>

                        <?php if ($counterz == $arz && $foresz['låst'] == "1") { //Skal kun udføres efter sidste celle/kolonne, hvis denne er låst?>
                          <input id="ub[<?php echo $tæller;?>][<?php echo $foresz['kolonnenr'];?>]" type="text" class="inputextrasmall" style="text-align:right;" name="p_udfort_belob[<?php echo $foresz['id'];?>][<?php echo $foresz['kolonnenr']+1;?>][]">
                        <?php }
                       
                        $counterz+=1;
                    }?>
                </ul>
        <?php } ?>
        <ul>
            <?php $tæller++;?>
            <input name="p_id[]" type="hidden" class="inputextrasmall" />
            <input name="p_navn[]" type="text" class="inputextrasmall" />
            <img src="/gfx/transparent.gif" style="width:100px;height:5px;" />
            <!--<input name="p_dato[]" type="text" class="inputextrasmall" />-->
            <input name="p_emne[]" type="text" class="inputextrasmall" />
            <input name="p_belob[]" type="text" class="inputextrasmall" />
        </ul>
        <ul>
            <img src="/gfx/transparent.gif" style="width:515px;height:5px;" />
            <?php for ($r=1;$r<$antal_kol;$r++) {?>
                <img src="/gfx/transparent.gif" style="width:101px;height:5px;" />
            <?php }?>
            <input name="laas" type="submit" value="Lås Aconto" class="submit" style="width:100px;"/>
        </ul>       
        <?php }
        unset($query);
        unset($query_ud);
        unset($position);?>
        <input type="hidden" name="tæller" value="<?php echo $tæller;?>" />         
    </div>

</table>
</div>
Avatar billede lsskaarup Nybegynder
28. december 2010 - 16:12 #2
Er nu kommet lidt videre, men er løbet ind i et andet problem.

Fra procesfilen laver jeg en header, der åbner frontend. Strukturen bliver lavet om via .htaccess
header('Location: /popupentreordre/ordre'.$nextpage.'/'.$ordre_id.'/#'.$anchor);

Er det muligt i frontend-filen, at fange hvad der står i $anchor?
Avatar billede tjens Nybegynder
28. december 2010 - 21:47 #3
#2 => Javascript adgang til anchor i URL fås via variablen window.location.hash
Avatar billede lsskaarup Nybegynder
28. december 2010 - 22:48 #4
Ja, det har jeg også fundet ud af, men hvordan kan jeg bruge den dynamisk?

Jeg vil gerne have at display i følgende blvier dynamisk, alt efter hvad window.location.hash er
<div id="id_kontrakt" style="display:block;">

Jeg tror dog jeg har løst problemet ved at gemme en information om typen i databasen, det er bare ikke satans elegant, så hvis der var en smartere måde, ville jeg meget gerne vide det.
Avatar billede tjens Nybegynder
29. december 2010 - 00:30 #5
Din kode har allerede en showhide() javascript funktion.

Hvis du allerede har en onload() funktion skal der vel tilføjes noget i stil med:
if (window.location.hash=='#kontakt')
{
  showhide('id_kontrakt');
}

Eller hvis anchor er lig med id:
showhide(window.location.hash.substring(1));
Avatar billede lsskaarup Nybegynder
29. december 2010 - 14:46 #6
Jeg har godt nok ikke en onload(), men det kunne jeg da få.

Men kan jeg sende 2 forskellige anchors med på denne måde?

Selvom min førnævnte metode ikke er den mest elegante, så giver den mig mulighed for at åbne 2 eller flere <ul>
Avatar billede tjens Nybegynder
29. december 2010 - 16:37 #7
Det er nok en unødig omvej at bruge anchors til at overføre information om hvilke felter der skal åbnes.

Du kunne i stedet opsamle informationen i backend-variable mens siden dannes, og så slutte af med at outputte et onload-script til klienten:

<script type="text/javascript">
window.onload = function () {
    showhide('id_kontrakt');
    showhide('id_felt2');
    showhide('id_felt3');
}
Avatar billede lsskaarup Nybegynder
29. december 2010 - 17:14 #8
Den er jeg er ikke lige helt med på tjens, gider du uddybe eksemplet?
Avatar billede tjens Nybegynder
30. december 2010 - 15:05 #9
Jeg glemte nok at skrive i #7, at jeg gætter på at siden som loades via din header i #2, også dannes dynamisk af PHP. Dermed må PHP vide hvor mange felter, der skal være åbne og lukkede, og kunne outputte javascript i stil med #7 dynamisk til sidst.

Hvis det skal være statisk serverside, kan du bruge anchor til normal positionering på siden, og så lave et javascript switch statement som lukker for felterne over det nævnte anchor:
<script type="text/javascript">
window.onload = function () {
  switch( window.location.hash.substring(1) ) {
    case "felt10":
      showhide('id_felt9');
    case "felt9":
      showhide('id_felt8');
    case "felt8":
      showhide('id_felt7');
    ...
      ...
  }
  // stil cursor i samme felt som siden er positioneret til:
  document.getElementById('id_' +window.location.hash.substring(1)).focus();
}
</script>

Læg mærke til at switch/case ikke indeholder break.
Derfor vil alle nedenstående statements blive udført når et match er fundet.
Og derfor spørges på nederste feltnavn først, og alle ovenstående felter spærres ud fra det navn der skal positioneres til ifølge anchor.
Avatar billede lsskaarup Nybegynder
30. december 2010 - 17:26 #10
Det er jeg stadig ikke helt med på...

Men lige for at afklare nogle ting, så er siden i headeren dynamisk. Altså det er selvfølgelig en fast side, men et dynamisk antal felter, og dynamisk indhold i disse. Data hertil trækkes fra databasen. Faktisk er header-siden samme som brugeren i første omgang indtastede data i.

Så processen bagved er således.
fronten side 1 -> backend processide 1 -> frontend side 1


Men tilbage dit forslag, for at se om jeg følger dig af den rigtige vej.

Som jeg forståer det så vil du have en onLoad på min frontend side 1. Funktionen showhide() skal vise(none) det felt, som kommer fra hash og samtidig lukke(block) alle de andre?
Avatar billede tjens Nybegynder
30. december 2010 - 18:20 #11
#10 Jeg går ud fra at din side viser alle felter (display:block)?
Og at showhide(id) bare skifter mellem display: none og block?
Og javascriptet vi arbejder på her, skal gøre en række elementer usynlige?

Hvis jeg forudsætter tre gange ja til ovenstående er ideen, at vi kalder showhide() på en række synlige elementer, og dermed bliver de usynlige.



Men hvis antal felter er dynamisk er det vel nemmest at sætte none/block direkte fra PHP mens siden dannes:
<?php
  if ($kontrakOK) {?>
    <div id="id_kontrakt" style="display:none;">
<?php } else { ?>
    <div id="id_kontrakt" style="display:block;">
<?php
  }
  ...

Så er der ikke behov for javascript.
Til gengæld skal du beregne $kontraktOK i mit eksempel her, eller på anden måde lave den if der bestemmer om afsnit kontrakt er synligt.
Avatar billede lsskaarup Nybegynder
30. december 2010 - 19:02 #12
#11
Det er ikke 3 ja'er, men tæt på. Alle felter er som standard skjult (display:none), ellers så passer det. Men det gør vel ikke den store forskel...

Men den sidste måde du nævner er faktisk den jeg har implementeret. Problemet i det, er at jeg bliver nød til at gemme hvilket felt, der senest er blevet ændret, i databasen. Dette skal jeg så på siden trække ud igen. Og betyder også, at jeg pt. kun kan vise én række felter, og jeg kan forestille mig, at brugerne gerne vil have alle ændrede rækker vist, men det er jeg altså ikke helt sikker på.
Avatar billede tjens Nybegynder
31. december 2010 - 00:34 #13
#12 OK, men så kan switch/case godt bruges:
Men feltrækkefølgen skal ikke være "omvendt" som i #9, hvor jeg troede at jeg skulle skjule dem der allerede var udfyldt.

Det skal blot være den rigtige felt-rækkefølge i case-linierne, hvis resten af felterne skal ændres fra skjulte til synlige.
Avatar billede lsskaarup Nybegynder
31. december 2010 - 11:55 #14
Altså?

    case "felt1":
      showhide('id_felt1');
    case "felt2":
      showhide('id_felt2');
    case "felt3":
      showhide('id_felt3');
    ...
      ...
Avatar billede tjens Nybegynder
31. december 2010 - 14:09 #15
Ja, hvis meningen er at det aktuelle felt og alle efterfølgende felter skal gøres synlige.


Og hvis antal felter (og dermed anchors) kan variere, skal du bygge det op i en PHP-string, mens siden dannes, og outputte det til sidst, pakket ind i en onload-funktion som vist i #9.
Avatar billede lsskaarup Nybegynder
01. januar 2010 - 11:45 #16
Nej, det er ikke det aktuelle og alle efterfølgende felter, der skal gøres synlige.

Der er 2 muligheder
1) Kun det felt, som brugeren sidst indtastede i gøres synlig.
2) Alle og kun de felter, som brugeren indtastede skal gøres synlige.
Avatar billede tjens Nybegynder
01. januar 2010 - 18:19 #17
mulighed 1) kan løses med en statisk onload() med dette i:
if (window.location.hash.length > 0) {
    showhide('id_' + window.location.hash.substring(1));
}
ud fra den navnestandard du selv bruger i #14.


mulighed 2) forstår jeg ikke meningen med.
Derudover: Hvordan ser man forskel på mulighed 1 og 2?
Avatar billede lsskaarup Nybegynder
01. januar 2010 - 21:58 #18
Det er fordi jeg ikke rigtig er klar over, om man kan sende flere "variabler" som hash.

Min siden er opbygget sådan, at brugeren kan folder mange "menuer" ud, hvor under der i hver er en række felter, som de kan indtaster. Systemet gemmer så alle felter, når de trykker gem.

Min høker-løsning pt. er at jeg smider feltets navn i et dertil indrettet felt, som jeg så gemmer i databasen, så kan jeg finde ud af at trække det ud på siden, og folder den rigtige menu ud. MEN jeg har kun et felt dertil, og det indeholder kun et feltnavn, så har brugeren indtastet i 5 felter, så vil det kun være den sidste der er åben. Gav det mere mening?
Avatar billede tjens Nybegynder
01. januar 2010 - 23:03 #19
Man kunne godt bruge split() på hash-værdien, og så have flere variable i den, adskilt af et udvalgt bogstav eller underscore.

Men jeg synes ikke, at det er den rigtige teknologi til at korttids-huske lidt data i klienten.

Jeg ved, at du vil sætte denne hash med serverside script, men kunne man ikke gøre det i klienten allerede ved første send?
Og så bruge en cookie i browseren til at huske status?
Avatar billede lsskaarup Nybegynder
01. januar 2010 - 23:29 #20
Jeg har ikke rodet med cookie før, så jeg ved ikke lige hvordan det skal gøres
Avatar billede tjens Nybegynder
02. januar 2010 - 10:20 #21
Cookies er meget nemt, og gør at man kan gemme variable i klienten.
Det er faktisk beregnet til at huske status fra sidste besøg, som du har brug for her.

Læs en tutorial om javascript og cookies.

Så en skitse til en løsning er:

- Opret en ny tom javascript Array() (global variabel)
- Din showhide() funktion udvides til at gemme id på afsnit der åbnes, i Array'et.
  Og fjerne afsnit der lukkes.
- En onsubmit() funktion på din form udvides til at gemme status på Array i en cookie.
- Onload() funktionen aflæser cookie, og kalder showhide() per element.

Herved vil din side altid have samme status som før submit, uden at du skal programmere noget serverside.

Og cookies har en expires parameter, så du selv bestemmer om status skal huskes i få sekunder, resten af dagen eller flere år.
Avatar billede lsskaarup Nybegynder
03. januar 2011 - 23:50 #22
Her længe tænkt, at jeg burde kigger nærmere på hvordan cookies skal bruges, men har aldrig fået taget mig sammen. Men dette kan være et godt incitament. Det må dog vente, da systemet meget snart skal gå i drigt, og så må brugerne nøjes med den nuværende funktionalitet indtil videre.

Men du skal have mange gange tak for hjælpen. Smid et svar, så du kan få nogle point.
Avatar billede tjens Nybegynder
03. januar 2011 - 23:52 #23
OK
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