Just nu i M3-nätverket
Gå till innehåll

Lista innehåll i mapp


Cluster

Rekommendera Poster

Skulle behöva någon snygg Ajax-lösning för följande scenario:

Har en mapp som löpande populeras med olika logfiler. Dessa loggfiler populeras vidare löpande med rader.

Skulle nu behöva visa upp info om/från dessa logfiler i en tabell i ett webbgränssnitt för en grupp användare. jag har inga problem att svänga ihop serversideskoden för att kolla mappen efter logfiler och för varje logfil ta ut den (rad) status som är aktuell.

Utmaningen är att få till det i ett dynamiskt och självuppdaterande "statusfönster".

 

Målet är alltså att få till en tabell med en ny rad för varje just nu befintlig logfil. Tabellen kommer ha två kolumner. En med logfilens namn och den andra med aktuell status (hämtas ut från sista raden i logfilen).

 

Om det tillkommer en logfil skall det alltså skapas en ny rad i tabellen. Om statusen i en logfil ändras skall kolumnen för status (i den rad som avser just den logfilen) uppdateras med den nya värdet.

 

Så länge som användaren har denna sida uppe så skall tabellen hållas automatiskt uppdaterad (osäker på vilket intervall som är lämpligt men ca 5 sekunder skulle jag kunna tänka mig).

 

Har googlat runt lite men hittar inget som gör exakt detta utan då ven en massa annat och jag har ingen lust att skala av allt annat för att få till bara detta. Inser även min begränsning i både tidstillgång och javascriptbriljans för att skriva det från scratch.

 

Någon som har något på lager eller har lust att svänga ihop något?

Länk till kommentar
Dela på andra webbplatser

Är det mycket data som skall skyfflas?

 

Bäst är om du kan ange datan i json-format och låtar js skapa en htmltabell. Jag tror att det går snabbast då.

 

5 sekunder låter lite frekvent, men det beror mycket på hur mycket data som skyfflas.

eventuellt kan man använda ajaxen för att pusha datan i en array eller bara uppdatera med ny data som läggs till i tabellen.

 

Kan du berätta lite mer ingående om det? (skicka mail om det är känslig information så lovar jag högsta sekretess ;)

Länk till kommentar
Dela på andra webbplatser

Tack för snabbt svar!

 

Nejdå det är inte mycket data antalet logfiler kanske blir ett par hundra där varje filnamn (ett av de värden som skickas) är 4-10 tecken. Statusen (det andra värdet som skall skickas) är även det bara ett fåtal tecken.

 

Har inga problem att låta anrop till serversidesskriptet svara med json - tror jag :)

 

Min första tanke var att man kallar på serversidesskripte toch får som svar (t.ex.) en tvådimensionell array med alla loggfiler och deras aktuella status. Dessa värden används sedan för att populera och/eller uppdarera html-tabellen.

Länk till kommentar
Dela på andra webbplatser

JSON verkar onödigt i detta fall, det enda det skulle tillföra är en container till en två-dimensionell array, så det räcker ju med att returnera bara den arrayen.

 

Kan du returnera på formatet

"var data=[[fil,status],[fil,status],[fil,status]]"

så är det ju bara att jämföra längden på den arrayen med din lokala räknare och sedan plocka ut de nytillkomnna raderna och pumpa in dem i tabellen, förslagsvis med jquery för att minimera huvudvärken.

Länk till kommentar
Dela på andra webbplatser

Här är allt du behöver (uppdatering var 10:e sekund):

    <script type="text/javascript">
       $(document).ready(function () {
           setInterval(statusTable.getUpdate, 10000);
       });
       var statusTable = {
           entryCount: 0,
           entries: [],
           getUpdate: function () {
               jQuery.ajax({
                   url: 'getData.ashx',
                   success: function (data) {
                       eval(data);
                       statusTable.entries = arr;
                       statusTable.updateTable();
                   }
               });
           },
           updateTable: function () {
               jQuery.each(statusTable.entries, function (idx, pair) {
                   if (idx >= statusTable.entryCount) {
                       jQuery("<tr><td>" + pair[0] + "</td><td>" + pair[1] + "</td>").appendTo("#tbl tbody");
                   }
               });
               statusTable.entryCount = statusTable.entries.length;
           }
       }

   </script>
   <table id="tbl"><tbody></tbody></table>

 

På serversidan skapar du strängen med javascript-arrayen,ex:

       public void ProcessRequest(HttpContext context)
       {
           context.Response.ContentType = "text/plain";
           context.Response.Write("var arr=[['fil1','status1'],['fil2','status2'],['fil3','status3']]");
       }

 

Glöm inte att inkludera jQuery också.

 

EDIT: Glömde timern, inlagd nu

Länk till kommentar
Dela på andra webbplatser

Tackar!

 

Efter att ha ändrat till

"var arr=[[fil,status],[fil,status],[fil,status]]"

så funkar det fint att få upp listan och att den utökas när det trillar in nya filer. :thumbsup:

 

Dock så ändras inte status (i tabellen) om status i filen ändras :(

Länk till kommentar
Dela på andra webbplatser

Ok, missade det kravet. Ändra den sista funktionen till följande så uppdaterar den övriga rader

            updateTable: function () {
               var t = jQuery("#tbl tbody tr td+td");
               jQuery.each(statusTable.entries, function (idx, pair) {
                   if (idx >= statusTable.entryCount) {
                       jQuery("<tr><td>" + pair[0] + "</td><td>" + pair[1] + "</td>").appendTo("#tbl tbody");
                   } else {
                       jQuery((jQuery(t)[idx])).text(pair[1]);
                   }
               });
               statusTable.entryCount = statusTable.entries.length;
           }

 

(det är alltså else-satsen som är det nya, samt tilldelningen av "t")

Länk till kommentar
Dela på andra webbplatser

Det funkar säkert bra om jag hade kunnat hålla mig från att själv försöka mig på att utöka funktionaliteten :blush:

 

Nu levererar mitt serversidesskript:

var arr=[[timestamp,filename,operation,status],[timestamp,filename,operation,status], osv...]

Detta petar jag med din hjälp sedan ini tabellen.

Dessutom så använder jag status-värdet (pair[3]) för att visa en fil bild.

 

Med din nya kod ser mitt skript nu ut såhär:

<script type="text/javascript">
$(document).ready(function () {
	setInterval(statusTable.getUpdate, 5000);
});
var statusTable = {
	entryCount: 0,
	entries: [],
	getUpdate: function () {
		jQuery.ajax({
			url: '/utils/getLogStatus/',
			success: function (data) {
				eval(data);
				statusTable.entries = arr;
				statusTable.updateTable();
			}
		});
	},
	updateTable: function () {
		var t = jQuery("#tbl tbody tr td+td");
		jQuery.each(statusTable.entries, function (idx, pair) {
			if (idx >= statusTable.entryCount) {
				varDateTime = pair[0];
				varFileName = pair[1];
				varOperation = pair[2];
				varStatus = pair[3];
				jQuery("<tr><td class='iconTd'><img src='/resources/images/icons/"+ varStatus +".gif' width='16' height='16'></td><td>" + varFileName + "</td><td>" + varDateTime + "</td><td>" + varOperation + "</td><td>" + varStatus + "</td>").appendTo("#tbl tbody");
	 } else {
				jQuery((jQuery(t)[idx])).text(pair[3]);
			}

		});
		statusTable.entryCount = statusTable.entries.length;
		$('table.striped tbody tr:not([th]):odd').addClass('odd');
		$('table.striped tbody tr:not([th]):even').addClass('even');
	}
}

</script>

 

Nu ändras "nästa" cell på samma rad, vilket förvisso ser kul ut men är inte det jag hade hoppats på :)

 

Det som "behöver" hända är att när värdena för TimeStamp och Status har ändrats (för ett FileName) skall det synas i respektive rad i tabellen. Dvs. tiden uppdateras och samma sak för statustexten samt bilden.

 

Är det görbart?

Länk till kommentar
Dela på andra webbplatser

Postar ett tillägg imorgon (om jag inte glömmer bort), just nu vart det sent efter att man fastnat framför Fallout:New Vegas =)

Länk till kommentar
Dela på andra webbplatser

Kanske inte så snygg kod, men det funkar iallafall. Du kan ju refaktorera själv om du vill.

 

updateTable: function () {
   var tds = jQuery("#tbl tbody tr").children();
   jQuery.each(statusTable.entries, function (idx, pair) {
       varDateTime = pair[0];
       varFileName = pair[1];
       varOperation = pair[2];
       varStatus = pair[3];
       if (idx >= statusTable.entryCount) {
           jQuery("<tr><td class='iconTd'><img src='images/" + varStatus + ".png' width='16' height='16'></td><td>" + varFileName + "</td><td>" + varDateTime + "</td><td>" + varOperation + "</td><td>" + varStatus + "</td>").appendTo("#tbl tbody");
       } else {
           var idx2 = idx * 5; // ANTAL CELLER
           jQuery(tds[idx2]).html("<img src='images/" + varStatus + ".png' width='16' height='16'>");
           jQuery(tds[idx2 + 1]).text(varFileName);
           jQuery(tds[idx2 + 2]).text(varDateTime);
           jQuery(tds[idx2 + 3]).text(varOperation);
           jQuery(tds[idx2 + 4]).text(varStatus);
           //jQuery((jQuery(t)[idx])).text(pair[3]);
       }
   });
   statusTable.entryCount = statusTable.entries.length;
   $('table.striped tbody tr:not([th]):odd').addClass('odd');
   $('table.striped tbody tr:not([th]):even').addClass('even');
},

Länk till kommentar
Dela på andra webbplatser

  • 4 veckor senare...

Vet inte riktigt vad som hänt... Det har fungerat bra fram till nu, men "helt plötsligt" har det slutat funka :(

Vissa saker har förvisso förändrats men det har skett utanför min kontroll så jag har inte koll på allt som skett.

Dock kan jag inte direkt se vad som ställt till det, så jag ber ödmjukt om lite hjälp.

 

När sidan körs så får jag felmeddelande (vid 5-sekundersuppdateringen):

Object doesn't support this property or method

Line: 135

Char: 226

Code: 0

URI: /js/jquery-1.4.4.min.js

Koden som körs ser ut såhär:

<script type="text/javascript" src="/js/jquery-1.4.4.min.js"></script>

<script type="text/javascript">
$(document).ready(function () {
	setInterval(statusTable.getUpdate, 5000);
});
var statusTable = {
	entryCount: 0,
	entries: [],
	getUpdate: function () {
		varUnique = new Date();
		$('.loadingTh').hide();
		$.post({
			url: '/utils/getLogStatus/',
			success: function (data) {
				eval(data);
				statusTable.entries = arr;
				statusTable.updateTable();
			}
		});
	},
updateTable: function () {
	var tds = jQuery("#tbl tbody tr").children();
	jQuery.each(statusTable.entries, function (idx, pair) {
		varStartDateTime = pair[0];
		varStopDateTime = pair[1];
		varComputerName = pair[2];
		varPkgName = pair[3];
		varOperation = pair[4];
		varStatus = pair[5];
		if (idx >= statusTable.entryCount) {
			jQuery("<tr><td class='iconTd'><img src='/images/icons/" + varStatus + ".gif' width='16' height='16'></td><td>" + varComputerName + "</td><td>" + varStartDateTime + "</td><td>" + varStopDateTime + "</td><td>" + varPkgName + "</td><td>" + varOperation + "</td><td>" + varStatus + "</td>").appendTo("#tbl tbody");
		} else {
			var idx2 = idx * 7;
			jQuery(tds[idx2]).html("<img src='/images/icons/" + varStatus + ".gif' width='16' height='16'>");
			jQuery(tds[idx2 + 1]).text(varComputerName);
			jQuery(tds[idx2 + 2]).text(varStartDateTime);
			jQuery(tds[idx2 + 3]).text(varStopDateTime);
			jQuery(tds[idx2 + 4]).text(varPkgName);
			jQuery(tds[idx2 + 5]).text(varOperation);
			jQuery(tds[idx2 + 6]).text(varStatus);
		}
	});
	statusTable.entryCount = statusTable.entries.length;
	$('table.striped tbody tr:not([th]):odd').addClass('odd');
	$('table.striped tbody tr:not([th]):even').addClass('even');
	}
}
</script>

<table id="tbl" class="striped">
<thead>
	<tr>
		<th colspan="2">Dator</th>
		<th>Start</th>
		<th>Stop</th>
		<th>Paket</th>
		<th>Aktivitet</th>
		<th>Status</th>
	<tr>
	<% IF strJobId<>"" THEN %>
	<tr><td colspan="7" class="loadingTh">Hämtar data...<td></tr>
	<% END IF %>
</thead>
<tbody>
<% IF strJobId="" THEN %>
	<tr><td colspan="7"><p>Hittade ingen data...</p><p> </p><td></tr>
<% END IF %>
</tbody>
</table>

 

Exempel-svar från serversidesscriptet:

var arr=[["2010-11-15 10:29:26","2010-11-15 10:29:28","XYZ123","PKG123","Insert","Completed"]]

Länk till kommentar
Dela på andra webbplatser

Titta man in jquery-filen så kraschar den när den försöker accessa ajax-objektets url-property. Varför är ju frågan då. Någon anledning till att du bytte från Ajax till Post?

Länk till kommentar
Dela på andra webbplatser

har du alltid kört med 1.4.4?

Nej, och jag är osäker på när man bytte och varför :)

 

Någon anledning till att du bytte från Ajax till Post?
Nej, och jag är osäker på när man bytte och varför :)

 

Hursomhelst så bytte jag tillbaks till jQuery.ajax (men lät det fortsatt vara jquery 1.4.4) och då fungerade det fint igen.

 

Borde såklart ha sett det själv men allt annat var samma och jag har inget textjämförelseprogram installerat på den här datorn...

 

Tack till er båda!

Länk till kommentar
Dela på andra webbplatser

Borde såklart ha sett det själv men allt annat var samma och jag har inget textjämförelseprogram installerat på den här datorn...

In med TFS =)

Konstigt att det fungerar nu. Post är, som jag förstår det, bara ett skal ovanpå Ajax och båda har ju parametern url och båda metoder har väl funnits med sedan jquerys födelse.

Ett tips som kan vara värt att ta till, nu när det verkar som du inte har full koll på vad andra gör, är att använda dig av objektreferensen jQuery istället för $ (eller definiera ett eget alias). Rätt som det är slänger någon in ett till tredjepartsbibliotek som också använder $ som global referens (det är en ganska populär sådan ;) och så slutar allt fungera och alla ser ut som frågetecken =)

Om du gör detta, kör följande först:

$.noConflict();

så släpper jQuery ägandeskapet av variabeln $

Länk till kommentar
Dela på andra webbplatser

Bra tips!

 

Ska vidarebefordra dem. Men främst ska jag se till att det inte är upp till mig att öht gå in och hjälpa till. Men ibland är man för snäll/hjälpsam ;)

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...