Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  17 2162
Heisan freaks and geeks, jeg trenger litt backup nok en gang.

Jeg sitter med en table som genereres dynamisk og ser sånn cirka slik ut:

Kode

<tr>
    <td><div class="editable"><%=data.getName_first() %></div></td
    <td></td>
    <td><div class="editable"><%=data.getName_last() %></div></td>
    <td></td>
    <td><%=data.getIdentifier() %></td>
tabell-genereringen skjer gjennom et databaseoppslag og kan varierere fra 1 til et par tusen så det er viktig at jeg slipper å derfinere alle navn.

Det er da <div class="editable"> jeg sliter med her. Jeg vil gjerne gjøre alle entry'er i tabellen redigerbare uten å endre hver enkelt gjennom databserunking. Jeg har et uferdig jQuery-script kladdet sammen som ser sånn ut:

Kode

$(document).ready(function(){
	$("div.editable").click(function(){
		var newInput = "<input type ='text' class='newInput' value=\""+$(this).text()+"\">";
		$(this).html(newInput);
		$("input.newInput").focus();
		//var original = $("#input.newInput").text();  hashtag(#)not working
		$("input.newInput").blur(function(){
		//	$(".editable").text(original); #
		});
		$("input.newInput").keypress(function(event){ // #lol, wat?
			if(event.which == 13){
				var value = $(this).val();
				$(".editable").text(value);				
			}
		});
	});
});
Dette er under utvikling og kan derfor på ingen måte anses som brukbart, og jeg vet at det ikke funker.
Det jeg lurer på er hvordan jeg kan hindre at scriptet kjører alle tabelloppføringene som èn. For om jeg redigerer en tabelloppføring nå så endres alle av keypress-funksjonen.
Litt dritt om alle fornavn endrer seg til Per da det kanskje bare er èn som heter Per.
#navn betyr at du vil ha elementet med id='navn'.

.navn betyr at du vil ha element(et) med class='navn'.

Og i det tilfellet vil ikke den originale være 'this'?

Tror .click() har elementet du har trykket på som context.

this.text() vil gi deg teksten til elementet trykket på (kanskje).
#D4AF37
moret's Avatar
Trådstarter
^
Ja, den er grei nok. Men om man tar utgangspunkt i denne forenklede versjonen:

Kode

$(document).ready(function(){
	$("div.editable").click(function(){
		var newInput = "<input type ='text' class='newInput' value=\""+$(this).text()+"\">";
		$(this).html(newInput);
		$("input.newInput").focus();
		$("input.newInput").keydown(function(event){
			if(event.which == 13){
				var value = $(this).val();
				$(".editable").text(value);
				//$(this).text(value);
			}
		});
	});
});
Så endres alle tabelloppføringene når jeg trykker taster enter i èn av de. Jeg vet jo at grunnen er at alle td'ene har class="editable", men hvordan kan jeg unngå dette?
Hva med å bruke .parent() til input feltet?

Kode

$("input.newInput").keydown(function(event){
    if(event.which == 13){
        var value = $(this).val();
        $(this).parent().text(value);
    }
});
Laget også en liten fiddle du kan prøve. Klikk!
Sist endret av hosjmeister; 2. januar 2013 kl. 17:34.
#D4AF37
moret's Avatar
Trådstarter
Aight, skal teste ut i morgen. Ty

Sitat av hosjmeister Vis innlegg
Hva med å bruke .parent() til input feltet?

Kode

$("input.newInput").keydown(function(event){
    if(event.which == 13){
        var value = $(this).val();
        $(this).parent().text(value);
    }
});
Laget også en liten fiddle du kan prøve. Klikk!
Vis hele sitatet...
Hey, dette funket jo gull
tyvm, så etter mange timer med hår-tap så var det bare en .parent som skulle til, typisk ass. Hahaha. Må se å lære meg jQuery ordentlig og ikke bare hacke sammen halvveis løsninger.
#D4AF37
moret's Avatar
Trådstarter
Okei, nytt problem her
Tenkte jeg bare oppdaterer denne så slipper jeg å lage en ny tråd da det omhandler omtrentlig det samme.
Igjen har jeg en div:

Kode

<div class="editable_select"><%=data.getIdentifiertype()%></div>
Jeg vil gjerne ha den slik at om jeg trykker på teksten der så får jeg en dropdown-select-thing:

Kode

<select name="selection"> 
  <option value="EN" >EN</option>
  <option value="TO" >TO</option>
  <option value="TRE" >TRE</option>
</select>
Av en eller annen grunn får jeg ingen respons på dette:

Kode

var select = '<select>';
   var options = [EN, TO, TRE];
   for(var i = 0; i < options.length;i++){
      select += '<option value="'+options[i]+'">'+options[i]+'</option>';
   }
   select += '</select>';
   $(this).html.(select);
Er det noen som ser en feil, eller om jeg er heeelt på tur her?
Setter veldig pris på svar.

Wooop. 4k innlegg

Vel, etter litt irc-hjelp av slicer ordnet det seg. Var bare å fjerne punktum etter html og legge til " rundt array-elementene.
Men, et nytt problem oppstår(aldri kan noe bare funke....). Jeg får ikke valgt noen av verdiene. Det er bare selecten som genereres, den gjør ingenting.
Kan det være grunnet at den blir kalt gjennom en slik:
$("div.editable_select").click(function(){

??
Sist endret av moret; 7. januar 2013 kl. 09:05.
Problemet er ganske enkelt. Listen ligger innenfor div-elementet. Når du klikker på listen, klikker du først på div'en. Da du har en lytter på div'en, som sier at et klikk på div'en skal lage listen på nytt, vil du ikke komme så langt som til å kunne velge element i listen.

En måte å gjøre det på, er å slutte å lytte etter klikk på div'en etter at listen har blitt generert.

Du må da gjøre ting i to omganger. Først skriver du funksjonen som skal kalles når man trykker på en div. Her genereres altså listen, og du slutter å lytte etter flere klikk. Deretter registrerer du en lytter på div'en, som sier at klikk skal kjøre funksjonen din.

For å starte å lytte etter en hendelse, kalles metoden 'bind', mens å slutte å lytte gjøres ved å kalle 'unbind'.

Kode

var f_click = function(){
  var select = '<select>';
   var options = ["EN", "TO", "TRE"];
   for(var i = 0; i < options.length;i++)
     select += '<option value="'+options[i]+'">'+options[i]+'</option>';
   
   select += '</select>';
    $(this).html(select);
    $(this).unbind('click',f_click);
}


$("div.editable_select").bind('click',f_click);
Du kan se hva jeg mener i jsfiddle.
#D4AF37
moret's Avatar
Trådstarter
Okei, skjønner. ty

Og får å få tak i den verdien som ligger der når jeg trykker, er det da bare å kalle typ:

Kode

 var i = $(this).val();
Sitat av moret Vis innlegg
Okei, skjønner. ty

Og får å få tak i den verdien som ligger der når jeg trykker, er det da bare å kalle typ:

Kode

 var i = $(this).val();
Vis hele sitatet...
Close.
Verdien som ligger i div'en finner du med

Kode

 var current = $(this).text();
#D4AF37
moret's Avatar
Trådstarter
Funketyfunky
Takk for hjelp! Settes stor pris på.

(kommer sikkert fler spørsmål etterhvert, fortsatt en god stund til jeg er dyktig nok i jQuery til å klare ting alene)
#D4AF37
moret's Avatar
Trådstarter
Okei. Nå står jeg igjen fast etter at jeg bestemte meg for å gjøre ting vanskelig igjen.
Om vi tar utgangspunkt i

Kode

var clickFunction = function(){
  var id = $(this).attr("id");
  var smallId = id.substr(10);
  var select = '<select name="select" id="select" onChange="HER MÅ DET VÆRE NOE?">'; 
  var options = ["ITEMNUMBER", "GROUP", "ALLITEMS"];
   for(var i = 0; i < options.length;i++)
     select += '<option value="'+options[i]+'">'+options[i]+'</option>';
     select += '</select>';
     $(this).html(select);
     $(this).unbind('click',clickFunction);
}
$("div.editable_select").bind('click',clickFunction);
});
Så kunne jeg tenkt meg at onChange'en sender den nye verdien jeg velger til en <input type="hidden" value="SENDES HIT">
Input type hidden genereres også dynamisk utifra en loop og vil da få navn som feks newValue_(iteratorverdi).
Jeg tenkte at å sette feks:

Kode

onChange="$('#newValue_'"'+smallId').value($(this).val());"
burde funke, men det blir for mange " og ' så stringen blir helt pult.
Det å opprette en

Kode

$("select").change(function(){
	$("select option:selected").each(function(){
		//something
	});
funker også dårlig da jeg må ha smallId'en for å vite hvilken newValue_* jeg skal bruke.. Er det i det hele tatt en måte å gjøre dette på?

Samme problemstilling gjelder også for
$("div.editable").click(function()'en.
Kunne tenkt meg at på

Kode

$("input.newInput").keydown(function(event){
if(event.which == 13){
så sendes den verdien som jeg har skrevet inn til en hidden. Også denne med navn som genereres på samme måte.
Her er en pastebin med kode i bruk:
http://pastebin.com/A7SW621X
Du kan bruke bind på samme måte som tidligere forklart, men denne gangen med argumenter.

Som du kan lese av dokumentasjonen (jQuery.bind()), tar metoden også data.

Det betyr at du kan gjøre noe a'la følgende:

Kode

$('select').bind('change', {id: smallId}, select_change);
Hvor da 'select_change' er metoden som kalles når det endres i select-listen.

For å få tak i ID'en som sendes inn, kan du gjøre følgende:

Kode

var select_change = function (arguments){
  var id = arguments.data.id;
  /*her kan du bruke id */
}
Ta gjerne en kikk på koden på jsFiddle (har forsøkt å inkludere input felt også).
Sist endret av hosjmeister; 10. januar 2013 kl. 16:11.
#D4AF37
moret's Avatar
Trådstarter
okei, sweet
Fikk et tips fra gutta på stackoverflow at kanskje noe sånt kunne funke:

Kode

<select name=&quot;dothis&quot; onChange=&quot;$('#newValue1_'+smallId+'').val($(this).val());&quot;
Men, har ikke fått testet det i dag.
#D4AF37
moret's Avatar
Trådstarter
Vel. Den selectboxen legger jeg på is inntil videre. Shitten funker ikke uansett hva jeg prøver på, så gidder ikke bry meg noe mer om det før jeg får en åpenbaring....


Men, det dukker alltids opp nye problemer, sånn for eksempel dette:

Jeg har en selectbox, som er en del av et form. Det er en veldig enkel selectbox og kan ses på som dette:

Kode

<select name="select1" id="select1">
   <option value="0">(choose one)</option>
   <option value="1">1</option>
   <option value="2">2</option>
   <option value="3">3</option>
</select>
Problemet mitt med denne er at formen er lenger enn hva som skal submittes. Sånn det er nå så er dette løst slik:

Kode

<select name="select1" id="select1" onChange="chooseComponent()"> (Dette er samme box, men tatt med onChangen)
Denne onChangen sender stuff til backend gjennom:

Kode

function chooseComponent() {
	document.TextForm.spec.value='chooseComponent';
	document.TextForm.submit();
}
Mitt problem enkelt forklart er at jeg vil ta bort onChangen og putte det inn i jQuery for å utvide funksjonaliteten ved å hide et par andre elementer i forhold til hva som velges i boxen. Selve hide-funksjonen funker, men jeg får ikke med meg form-submitten. Nå ser det ruffly slik ut

Kode

$(document).ready(function(){
	$("#component_locale_ri").change(function(){		
		$("#editAdminComponentTextForm").submit();
		/*HER VIL JEG PÅ EN MÅTE HA INN
                 function chooseComponent() {
	             document.TextForm.spec.value='chooseComponent';
	             document.TextForm.submit();
                 }  */
		if($(this).val() != "0") {
			$("#hide1").slideDown("fast");
		}else{
			$("#hide1").SlideUp("fast");
		}
	});
Er det en måte å oversette form-submitten med tanke på spec.value ='chooseComponent' til jQuery?
Håper jeg har forstått deg riktig. Det første forslaget gjør stort sett det samme som chooseComponent() funksjonen din.

Kode

        $('form[name="TextForm"]').find('input[name="spec"]').value("chooseComponent");
        $('form[name="TextForm"]').submit();
Mitt andre forslag er en enklere løsning dersom hensikten kun er å poste data. Første parameter er URL du ønsker å poste til (samme som action="" i formet), og det andre parameteret er array med data du ønsker å sende.

Kode

        $.post('/', { spec: 'chooseComponent' });
Sist endret av danielsk; 19. januar 2013 kl. 21:56.
#D4AF37
moret's Avatar
Trådstarter
Sitat av danielsk Vis innlegg
Håper jeg har forstått deg riktig. Det første forslaget gjør stort sett det samme som chooseComponent() funksjonen din.

Kode

        $('form[name="TextForm"]').find('input[name="spec"]').value("chooseComponent");
        $('form[name="TextForm"]').submit();
Mitt andre forslag er en enklere løsning dersom hensikten kun er å poste data. Første parameter er URL du ønsker å poste til (samme som action="" i formet), og det andre parameteret er array med data du ønsker å sende.

Kode

        $.post('/', { spec: 'chooseComponent' });
Vis hele sitatet...
Yes.
Jeg glemte å oppdatere tråden, men jeg fant en måte å gjøre det på etter litt irc-hjelp. Ligner veldig på ditt forslag
▼ ... noen uker senere ... ▼
#D4AF37
moret's Avatar
Trådstarter
Okei okei. En liten update.
Jeg er nå i mål, etter mye om og men, og er relativt fornøyd med løsningen all over. Noe pynting og opprydding kan sikkert gjøres men det får jeg ta en annen gang. Shitten funker ihvertfall og jeg tenkte å dele koden sånn tilfelle noen trenger noe lignende. Som sagt, det er ikke den mest sexy koden i historien, men jeg lar hver enkelt rydde og pynte selv jeg anser meg som relativt ferdig og orker ikke gjøre noe videre jobb akkurat nå for å legge til sexyness.
Okei, så først. Utgangspunktet mitt var en slik listing:


Den genereres fra backend gjennom denne koden:

Kode

<table id="dataTable">
 <tr>
	<td>Identifiertype</td>
	<td width="10"></td>
	<td>Identifier</td>
	<td width="10"></td>
	<td>Info</td>
	<td width="30"></td>
	<td>Markup</td>
	<td width="10"></td>
	<td>Netprice</td>
	<td width="10"></td>
	<td></td>
 </tr>
 <br/>
<%
int iterator = 0;
for(Iterator it = db.getData().iterator();it.hasNext();) {
	EntryData entry = (EntryData)it.next();
	
%>
	<tr>
		<td><div id="editable1_<%=iterator%>" class="editable_select" onBlur="reset();" name="editable_select"><%=entry.getIdentifiertype()%></div><input type="hidden" id="newValue1_<%=iterator%>" value=""></td>
		<td></td>
		<td><div id="editable2_<%=iterator%>" class="editable"><%=entry.getIdentifier()%></div><input type="hidden" id="newValue2_<%=iterator%>" value="">
		<td></td>
		<td><%=entry.getIdentifierTitle() %></td>
		<td></td>	    
		<td><div id="editable3_<%=iterator%>" class="editable"><%if(entry.getEntrytype().equals("MARKUP")){out.println(entry.getEntrycontent());} %></div><input type="hidden" id="newValue3_<%=iterator%>" value=""></td>
		<td></td>
		<td><div id="editable4_<%=iterator%>" class="editable"><%if(entry.getEntrytype().equals("NETPRICE")){out.println(entry.getEntrycontent());} %></div><input type="hidden" id="newValue4_<%=iterator%>" value=""></td>
		<td></td>
		<td><input type="hidden" value="<%= entry.getIdentifiertype() %>" name="original_Identifiertype_<%=iterator%>" id="original_Identifiertype_<%=iterator%>"/></td>
		<td><input type="hidden" value="<%= entry.getEntrycontent() %>" name="original_EntryContent_<%=iterator%>" id="original_EntryContent_<%=iterator%>"/></td>		
		<td><input type="hidden" value="<%= entry.getIdentifier() %>" name="original_Identifier_<%=iterator%>" id="original_Identifier_<%=iterator%>"/></td>
		<td><input type="hidden" value="<%= entry.getEntrycontent() %>" name="original_Entrytype_<%=iterator%>" id="original_Entrytype_<%=iterator%>"/></td>
		<td><input type="hidden" value="<%=iterator%>" name="iterator"/></td>
	</tr>
<% 
iterator++;} 
%>

 </table>
Så, for å forklare litt så brukes hidden-verdiene av backend for database-kjøring. Min backend er en javaløsning med en tilhørende oracle-database for de som interesserer seg for sånt. Det er vel såpass mye jeg gidder å gå ut med.

Det jeg opprinnelig ønsket å gjøre var å kunne trykke på hvilken som helst verdi og endre denne. Rett og slett for å slippe å slette og legge inn på nytt , som var den eneste muligheten tidligere.
Som man kan se så er har hver enkelt verdi en egen div med en editable_iterator-verdi, det er så jeg kan legge jquery-funksjonalitet på hver eneste verdi. Etter at en verdi er endret så legges den nye verdien til sitt tilhørende hidden-felt(newvalue_) som backend bruker sammen med original_Whatever-felt for å gjøre oppslag og database-endringer(man kan sikkert unngå bruk av de hidden original_value feltene, men som sagt det funker og pynting får du gjøre sjøl).

Okei, så noe av problemet var at jeg ville ha en dropdown-meny om jeg klikket på verdiene som ligger i identifiertype-rekken. Fordi man kan banne på at en eller annen jævel ikke klarer å skrive "ITEMNUMBER" riktig, så da skulle man bare få velge mellom de valg jeg bestemmer. For andre verdier så skulle man kunne skrive inn sjøl.
Jeg la til en knapp som slides fram, ved trykk på denne så submitter man formet tabellen er en del av til backend. Denne heter "updateData" om noen lurer.
Så, over til jQuery-koden:

Kode

<script type="text/javascript">
/*omfg. lulz to the lol. Edit in place-funskjonalitet for tabellene. */
$(document).ready(function(){
	$("div.editable").click(function(){  //Denne funksjonen funker på tekstfeltene som man kan editere selv.
		var newInput = "<input type ='text' class='newInput' value=\""+$(this).text()+"\">"; //definerer en string som "erstatter" opprinnelig kode ved trykk 
		$(this).html(newInput); //selve erstatningsfunkjsonen
		var id = $(this).attr("id");	//henter ut id'en til verdien 
		$("input.newInput").focus(); //setter det nye lagede input-feltet i fokus
		$("input.newInput").keydown(function(event){
			if(event.which == 13){	//ved trykk på enter...
				var value = $(this).val();
				var str = id;    //Okei, dette er id'en til elementet. 
				var strArray = str.match(/(\d+)/g); //her plukker jeg ut tallene fra id'en og legger dem i en array så jeg kan bruke dem til å tilegne den nye verdien til riktig input-felt
			 	for(var i = 0;i<strArray.length;i++){	//her looper jeg gjennom arrayen og henter ut hvert enkelt tall. Dette er drittstygt, men igjen; pynte får du gjøre sjøl			
					if(i == 0){var temp0 = strArray[i];} 
					if(i == 1){var temp1 = strArray[i];}
				}
			 	$("#newValue"+temp0+"_"+temp1).val(value); //her slenger vi den nye verdien til tilegnet hidden-felt.
			 	$(this).blur(); //bare for å loose focus ved entertrykket
			 	slide(); //slider fram update-knappen
			}
		});
	});
});
 $(window).load(function(){
	var clickFunction = function(){
	  var id = $(this).attr("id"); //henter id igjen	  
	  var select = '<select name="select" id="'+id+'" onChange="changeFunction();">'; //en ny textstring som vi "printer ut" i html og dermed erstatter koden som ligger der fra før..
	  var options = ["ITEMNUMBER", "GROUP", "ALLITEMS"]; //array med de verdier jeg vil ha inn i dropdownen
	   for(var i = 0;i<options.length;i++)
	     select += '<option value="'+options[i]+'">'+options[i]+'</option>';
	     select += '</select>'; //populerer droipdownen med array-verdiene
	     $(this).html(select);//skriver ut den stringen
	     $(this).unbind('click',clickFunction); //unbindfunksjon for click
	}
	$("div.editable_select").bind('click',clickFunction); //bindfunksjon for click
});
$('#dataTable select[name^="select"]').live('change', (function () { //denne er gull da jeg eliminerte problemet med at onChange fikk for mange "s og 's. Nå er dette selve onChange-funksjonen, sort of
    var value1 = ($("option:selected", this).val()); //valgt value i dropdownen heter nå value1
    var id = $(this).attr("id"); //henter ut id'en til verdien
    var str2 = id;                                  
	var str2Array = str2.match(/(\d+)/g); //sammen styggge hack som over
	for(var i = 0;i<str2Array.length;i++){				
		if(i == 0){var temp01 = str2Array[i];} 
		if(i == 1){var temp11 = str2Array[i];}
	}
    $("#newValue"+temp01+"_"+temp11).val(value1); //tilegner den nye verdien til tilhørende hidden-felt
    slide(); //slider fram update knappen
}));
function slide(){
		$("#updateData").slideDown("fast"); //selve funkjsonen som gjør at updateknappen på magisk vis popper opp ved endringer i tabellen 
}
$(function(){
	$('#updateData').click(function(){
		updateFunksjonTilBackend(); //knappens onclick som sender inn formet for update
	});
});
/*jepp, det var alt */
Oh. koden for knappen

Kode

<input type="button" name="updateData" id="updateData" value="update data" style="display:none;"/>
Som sagt, det er en del hacks og stygge løsninger. Men, overall så funker det bra. Jeg er ikke en veldig erfaren webutvikler så det finnes sikkert mer elegante lønsinger å gjøre det på (kom gjerne med input og tips til forbedringer).
Men, jeg ville gjøre det selv og ikke bruke feks jeditable, selv om det sikkert er en mye bedre løsning. Synes også at mine 50-60 linjer med jquery fungerte like så bra for min del som jeditalbe sine mange hundre linjer.

Så, om folk ikke slakter meg totalt hadde det vært hyggelig
Jeg begynte jo på dette ned ~0 jquery-kunnskap. Seriøst, helt grønn

[COLOR="White"]Tilfelle noen googlesøker (lol, verb): jquery, edit in place, dynamic change to html, jquery selectbox, jquery edit[/COLOR]
#D4AF37
moret's Avatar
Trådstarter
Oioi. Nytt problem folkens:

Jeg tenkte å pynte litt på shitten jeg har produsert her.
En av ideene jeg kunne tenkt meg er at etter du trykker på enter i tekstboxene som dukker opp eller velger noe i dropdownen så forsvinner da enten tekstfeltet eller dropdownen og så blir tabellen bare ren tekst igjen. Da med den nye verdien som tekst.
Dette funker veldig greit med de vanlige editable-feltene. Da med denne koden:

Kode

$("#editable" +temp0+"_"+temp1).text($(this).val());
Den funker plettfritt.

Men, dessverre så gjør det ikke det med dropdownen. Om jeg velger en verdi så forsvinner selve boxen, og verdien endres fra opprinnelig til ny tekst. Problemet er at jeg bare kan endre dette èn gang. Om jeg prøver å trykke for å endre igjen så er ikke den nye teksten clickable. Det er litt dust.
Noen som har en idé for hvordan jeg kan løse dette?