root/ui/web/htdocs/graph_panel.inc

Revision 21720f443fc4436e839bfadf21de9c6fd47366e0, 21.7 kB (checked in by Umar Farooq <umar@omniti.com>, 9 years ago)

upgrading jquery to 1.3.2, and jquery-ui to 1.7.2.
adding slider to allow toggling of polltimerefs #147

  • Property mode set to 100644
Line 
1 <script type="text/javascript">
2 <!--
3 var maingraph;
4 var current_graph_id = '';
5 var debug_graph_edit = false;
6 var graphinfo= {};
7 var displayinfo = { start : 14*86400, cnt: '', end: '' };
8 var color_pool = Array('#33aa33','#4a00dc','#caac00','#3377cc','#00acfa','#cc3333')
9 var color_sel = 0;
10 var locked = true;
11
12 function graph_locked(warning) {               
13   if(locked) {
14     modal_warning("Graph Locked!", warning);
15     return locked;
16   }
17   return locked;
18 }
19
20 function lock_forms() {
21         $("input[name='math1']").attr("disabled", "true");
22         $("input[name='math2']").attr("disabled", "true");
23         $("input[name='view']").attr("disabled", "true");
24         $("input[class='graphType']").attr("disabled", "true");
25         $("select[name='derive']").attr("disabled", "true");
26         $("select[class='av_stacks']").attr("disabled", "true");
27
28         $("h2#graphTitle").unbind();
29         $(".datatitle").unbind();
30 }
31
32 function unlock_forms() {
33
34         $("input[name='math1']").removeAttr("disabled");
35         $("input[name='math2']").removeAttr("disabled");
36         $("input[name='view']").removeAttr("disabled");
37         //leave the graph type disabled, since we dont use it anywhere rightnow
38         //$("input[class='graphType']").removeAttr("disabled");
39         $("select[name='derive']").removeAttr("disabled");
40         $("select[class='av_stacks']").removeAttr("disabled");
41
42         $("h2#graphTitle").editable(function(value, settings) {
43            graphinfo.title = value;
44            update_current_graph(false);
45            return(value);
46            }, { });
47
48         $(".datatitle").editable(function(value, settings) {     
49            graphinfo.datapoints[$(".datatitle").index(this)].name = value;
50            update_current_graph(true);
51            return(value);
52         }, { });
53 }
54
55 function update_graph_permalink(id, start, end, gran){
56  $("#gpermalink a").attr("href", "drawing_board.php?otype=graph&id="+id+"&start="+start+"&end="+end+"&gran="+gran);
57 }
58
59 function stop_streaming_graph (){
60          streaming = false;
61          $('#streambox').html('');
62          $(".stream-log").attr("style", "display:none;");
63          $("#graph_datetool").css("display", "");
64          $("#play_pause_graph").html('PLAY');
65 }
66 //overlay mode: stackadd=false: we just add new stacks for any the incoming graph has
67 //stack mode: stackadd=trule, push new stacks onto matching stack indexes, else append
68 function aggregate_graph(id, stackadd) {
69   if(!graph_locked("Click 'Edit Graph' to unlock.")){
70          if(id) $.getJSON("json/graph/info/" + id, function(g) {
71
72                 var max_old = (graphinfo.datapoints.length) ?  graphinfo.datapoints.length : 0;
73
74                 for(var i=0; i<g.datapoints.length; i++) {
75                         graphinfo.datapoints.push(g.datapoints[i]);
76                 }       
77
78                 if(g.stacks) {
79                   //we must use indexes for datapoints that are updated
80                   for(var i=0; i<g.stacks.length; i++) {
81                     for(var j=0; j<g.stacks[i].length; j++) {
82                       g.stacks[i][j] += max_old;
83                     }
84                   }
85
86                   if(stackadd) {
87                     for(var i=0; i<g.stacks.length; i++){
88                           if(graphinfo.stacks[i]) graphinfo.stacks[i] = graphinfo.stacks[i].concat(g.stacks[i]);
89                           else graphinfo.stacks.push(g.stacks[i]);
90                     }                     
91                   }     
92                   else {
93                      for(var i=0; i<g.stacks.length; i++){
94                            graphinfo.stacks.push(g.stacks[i]);
95                      }
96                   }
97                }
98                 update_current_graph(true);
99                 refresh_graph_from_json(graphinfo);
100               });
101   }
102 }
103
104 function set_current_graph_id(id) {
105   streaming = false; //precautionary
106   $(".rememberGraph").fadeOut('fast');
107   if(id!='')  {
108     graphinfo.saved = true;
109     locked = true;
110     lock_forms();
111     $(".editGraph").html('Edit Graph').fadeIn('slow');   
112   }
113   else {       
114     locked = false;
115     unlock_forms();   
116     $(".editGraph").html('Editing!').fadeIn('slow');
117     stop_streaming_graph();
118   }
119   current_graph_id = id;
120   update_graph_permalink(current_graph_id, "", "", "");
121   fetch_graph_info(current_graph_id);
122 }
123 var recurse = 0;
124 function update_current_graph(redraw, f) {
125   if(recurse > 0) return;
126   stop_streaming_graph();
127   if(graphinfo.id) update_graph_permalink(current_graph_id, "", "", "");
128   var str = JSON.stringify(graphinfo);
129   if(debug_graph_edit) $("#payload").html(str);
130   $.post("json/graph/store",
131          {'json':str},
132          function(d) {
133            recurse++;
134            graphinfo.id = current_graph_id = d.id;
135            
136            if(d.error) $("#gtool-error").html(d.error).fadeIn('fast');
137            else $("#gtool-error").fadeOut('fast');     
138            if(graphinfo.id && graphinfo.saved != true &&
139               $(".rememberGraph:visible").length == 0) {
140               graphinfo.saved=false;
141              $(".rememberGraph").html('"Remember" this graph.').fadeIn('slow');
142              $(".rememberGraph").click(function() {
143                graphinfo.saved = true;
144                if(graphinfo.stacks == undefined) graphinfo.stacks = Array();
145                update_current_graph(false, function(r) {
146                  if(r.error) {
147                    graphinfo.saved = false;
148                     $("#gtool-error").html(r.error).fadeIn('fast');
149                  }
150                  else $(".rememberGraph").html('Remebered').fadeOut('slow');
151                });
152              });
153            }
154            if(redraw && maingraph) maingraph.ReconGraphRefresh({graphid: graphinfo.id, type: graphinfo.type});
155            if(f) f(d);
156            recurse--;
157          }, 'json');
158 }
159
160 function graph_add_datapoint(d) {
161   if(!graph_locked("Click 'Edit Graph' to unlock.")){
162     if(d.axis == undefined) { d.axis = 'l'; }
163     if(d.name == undefined) { d.name = d.target + '`' + d.metric_name; }
164     graphinfo.datapoints.push(d);
165     gtool_add_datapoint(d);
166     update_current_graph(true);
167   }
168 }
169 function gtool_add_guide() {
170   var d = {};
171   d.metric_type = 'guide';
172   graphinfo.datapoints.push(d);
173   gtool_add_datapoint(d);
174   update_current_graph(true);
175 }
176
177 function gtool_add_datapoint(d) {
178   var o;
179   if(d.metric_type == 'guide') {
180     o = $("#guideeditor").clone();
181   }
182   else {
183     o = $("#datapointeditor").clone();
184   }
185   recurse++;
186  
187   if(d.color == null) {
188     d.color = color_pool[color_sel];
189     color_sel = (color_sel + 1) % color_pool.length;
190   }
191   o.find('.colorPickerHolder').ColorPicker({
192     flat: true,
193     color: '#ffffff',
194     onSubmit: (function(dpo,dp) {
195       var cs = dpo.find('.colorSelector');
196       return function(hsb, hex, rgb) {
197         dp.color = '#' + hex;
198         cs.css('border', '1px solid ' + dp.color);
199         cs.find('div').css('backgroundColor', dp.color)
200                       .css('opacity', 0.2);
201         cs.parent().find('.colorPickerHolder').stop().animate({height:0},500);
202         update_current_graph(true);
203       }
204     })(o,d)
205   });
206   o.find('.colorPickerHolder > div').css('position', 'absolute');
207   o.find('.colorSelector').css('border', '1px solid ' + d.color);
208   o.find('.colorSelector div').css('backgroundColor', d.color)
209                               .css('opacity',
210                                    (d.opacity == null) ? 0.2 : d.opacity);
211   o.find('.colorSelector').bind('click', function() {
212     if(!locked){
213         var activecp = $(this).parent().find('.colorPickerHolder');
214         var h = activecp.height();
215         $("#gtool #dataPoints .colorPickerHolder").filter(function(index) {
216              return ($(this) != activecp);
217         }).stop().animate({height:0}, 0);;
218         $(this).parent().find('.colorPickerHolder').stop().animate({height: h != 0 ? 0 : 173}, 500);
219     }
220   });
221
222   o.find(d.axis == "l" ? ".axisl" : ".axisr").addClass("axison");
223   o.find("span.axis").click(function(){
224     if(!locked) {
225        $(this).siblings().removeClass("axison");
226        $(this).addClass("axison");
227        d.axis = $(this).hasClass("axisl") ? "l" : "r";
228        update_current_graph(true);
229     }
230   });
231
232   if(!d.hidden){o.find('input[name="view"]').attr("checked","checked");}
233   o.find('input[name="view"]').change(function(){
234     d.hidden = !($(this).attr("checked"));
235     update_current_graph(true);
236   }).change();
237
238   o.find('select[id="datastack"]').change(function(){
239       var si = find_in_stacks($(".av_stacks").index(this));
240        if(si != -1) graphinfo.stacks[si.i].splice(si.j, 1);
241
242        if(graphinfo.stacks[ $(this).val() ]) {
243          graphinfo.stacks[ $(this).val()].push($(".av_stacks").index(this));
244          graphinfo.stacks[ $(this).val()].sort(function(a,b){return a - b});
245        }
246        update_current_graph(true);
247
248       $(".graphStacks").empty();
249
250       for(var i=0; i<graphinfo.stacks.length; i++) {
251         $(".graphStacks").append('<br>Stack '+i+': ');
252         for(var j=0; j<graphinfo.stacks[i].length; j++){
253             $(".graphStacks").append(graphinfo.datapoints[graphinfo.stacks[i][j]].name + ",");
254         }
255       }
256     }).change();
257
258
259   o.find('.deletedatapoint').click(function(){
260     if(!locked){
261        for(var i=0; i<graphinfo.datapoints.length; i++) {
262          if(graphinfo.datapoints[i] == d) {
263            graphinfo.datapoints.splice(i,1);
264            var si = find_in_stacks(i);
265            if(si != -1) graphinfo.stacks[si.i].splice(si.j, 1);
266
267            //we must decrement the datapoint indexes in the stack array as well
268            for(var k=0; k<graphinfo.stacks.length; k++) {
269              for(var j=0; j<graphinfo.stacks[k].length; j++) {
270                if(graphinfo.stacks[k][j]>i) graphinfo.stacks[k][j]-=1;
271              }
272            }       
273
274            break;
275          }
276        }         
277           update_current_graph(true);
278           refresh_graph_from_json(graphinfo);
279        }
280     return false;
281   });
282
283   if(d.metric_type == 'text') {
284     o.find('tr.mathbox').remove();
285     o.find('select[name="derive"]').val('false');
286   }
287   else {
288     if(d.derive){
289       o.find('select[name="derive"]').val(d.derive);
290     }
291     o.find('select[name="derive"]').change(function(){
292       d.derive = $(this).find(":selected").val();
293       update_current_graph(true);
294     }).change();
295
296     o.find('input[name="math1"]').val(d.math1);
297     o.find('input[name="math1"]').change(function(){
298       d.math1 = $(this).val();
299       update_current_graph(true);
300     });
301     o.find('input[name="math2"]').val(d.math2);
302     o.find('input[name="math2"]').change(function(){
303       d.math2 = $(this).val();
304       update_current_graph(true);
305     });
306   }
307
308   d.mouse_title = ( (d.target!=undefined) ? d.target+"`": '') +
309                         ( (d.module!=undefined) ? d.module+"`": '') +
310                         ( (d.orig_name!=undefined)? d.orig_name+"`": '') +
311                         ( (d.metric_name!=undefined)? "`"+d.metric_name: '');
312
313   o.find(".datatitle").html(d.name);
314   o.find(".datatitle").attr("title", d.mouse_title);
315
316   if (!locked) {
317       o.find(".datatitle").editable(function(value, settings) {
318       graphinfo.datapoints[$(".datatitle").index(this)].name = value;
319       update_current_graph(true);
320       return(value);
321     }, { });
322  }
323
324   recurse--;
325   $("#gtool #dataPoints").append(o.children());
326 }
327
328 function find_in_stacks(dnum) {
329   for(var i=0; i<graphinfo.stacks.length; i++) {
330       for(var j=0; j<graphinfo.stacks[i].length; j++) {
331          if(graphinfo.stacks[i][j] == dnum) {           
332             var r = { i: i, j: j}; return r;
333          }       
334       }
335   }
336   return -1;
337 }
338 //this function works on the maingraph dom element, which is used througout in graph editing
339 function refresh_graph_from_json(j) {
340   graphinfo = j;
341   if(graphinfo.stacks == undefined) graphinfo.stacks = Array();
342   if(graphinfo.datapoints == undefined) graphinfo.datapoints = Array();
343   $("h2#graphTitle").html(graphinfo.title ? graphinfo.title : 'Graph Title (click to edit)');
344
345   $("input[name='graphtype']:checked").removeAttr("checked");
346   $("input[name='graphtype']")
347     .filter(function(i){return $(this).val() == graphinfo.type;})
348     .attr("checked","checked");
349   $("#dataPoints").empty();
350
351   for(var i=0; i<graphinfo.datapoints.length; i++) {
352     gtool_add_datapoint(graphinfo.datapoints[i]);
353   }
354
355   $(".graphStacks").empty();
356   $('.av_stacks').find('option').remove().end().append('<option value="-1">select </option>')
357
358   for(var i=0; i<graphinfo.stacks.length; i++) {
359     $(".graphStacks").append('<br>Stack '+i+': ');     
360     $('.av_stacks').append('<option value="'+i+'">Stack '+i+'</option>');
361
362     for(var j=0; j<graphinfo.stacks[i].length; j++){
363         $(".graphStacks").append(graphinfo.datapoints[graphinfo.stacks[i][j]].name + ",");
364     }
365   }
366
367   $('select[id="datastack"]').each( function()  {   
368     var si = find_in_stacks($(".av_stacks").index(this));
369     if(si != -1) $(this).val(si.i);
370   });
371
372   if(maingraph) {
373     if(graphinfo.id)
374       maingraph.ReconGraphRefresh({graphid: graphinfo.id, type: graphinfo.type, stacks: graphinfo.stacks});
375     else
376       maingraph.ReconGraphReset();
377   }
378 }
379 function fetch_graph_info(id) {
380   graphinfo.id = id;
381   if(id) $.getJSON("json/graph/info/" + id, refresh_graph_from_json);
382   else refresh_graph_from_json({});
383 }
384 -->
385 </script>
386 <!--<p><a href="">username</a> / <a href="#">worksheet</a></p>-->
387 <p/>
388 <span class="rememberGraph"></span>
389 <span class="blankGraph">New Blank</span>
390 <span class="stream_controls">
391 <span id="play_pause_graph">PLAY</span>
392 <span id="stopstream_graph">STOP</span>
393 </span>
394 <span class="editGraph">Edit Graph</span>
395 <span class="permalink" id="gpermalink"><a href="">Link</a></span>
396
397 <h2 id="graphTitle"></h2>
398 <!-- date range box -->
399 <script type="text/javascript">
400 $(document).ready(function(){
401
402         lock_forms();
403
404         var time_windows = { '2d' : 86400*2,
405                               '1w' : 86400*7,
406                               '2w' : 86400*14,
407                               '4w' : 86400*28,
408                               '1y' : 86400*365,
409                             };
410         var state = false;
411
412         //only allow graph editing if not streaming
413         $(".editGraph").click(function() {     
414             if(!streaming){
415                 if(locked){
416                     locked = false;                 
417                     unlock_forms();
418                     $(".editGraph").html('Editing!').fadeIn('slow');
419                 }
420                 else if(!locked){
421                     locked = true;     
422                     lock_forms();
423                     $(".editGraph").html('Edit Graph').fadeIn('slow');
424                 }
425             }
426         });
427
428         $(".editStacks").click(function() {
429                if(!graph_locked("Unlock by clicking 'Edit Graph'.") && graphinfo.id) {                         
430                  graphinfo.stacks.push([]);
431                  var ns = graphinfo.stacks.length - 1;
432                  $(".graphStacks").append('<p>Stack '+ns+'</p>');
433                  $('.av_stacks').append('<option value="'+ns+'">Stack '+ns+'</option>');
434                  update_current_graph(true);
435                }
436        });                                             
437        
438        //only allow stream toggling if the graph is locked and saved
439        $("#play_pause_graph").click(function() {
440          if(locked && graphinfo.saved) {
441           if($(this).html() == 'PLAY') {
442             $(this).html('PAUSE');
443             //if we are playing for the frist time
444             if(!streaming) {
445               $('#graph_datetool').css("display", "none");
446               $(".stream-log").removeAttr("style").html("stream log_");
447             }
448             //setup/restart the plotting
449             stream_data(graphinfo.id, maingraph, $('#streambox'));
450           }
451           else if($(this).html() == 'PAUSE') {
452              $(this).html('PLAY');
453              //this is where we pause for a bit
454              maingraph.stopTime();
455           }
456         }
457        });
458
459        $("#stopstream_graph").click(function() {
460         stop_streaming_graph();
461         update_current_graph(true);
462        });
463
464         $("#graph_datetool .btn-slide").click(function(){
465                 $("#graph_widgetCalendar").stop().animate({
466                      height: state ? 0 :
467                        $('#graph_widgetCalendar div.datepicker').get(0).offsetHeight
468                   }, 500);
469                 state = !state;
470                 $(this).toggleClass("active");
471                 return false;
472         });
473         $("#graph_datetool .datechoice").click(function(){
474                 $("#graph_datetool .range a.btn-slide").html("YYYY/MM/DD - YYYY/MM/DD");
475                 $("#graph_widgetCalendar").slideUp("slow");
476                 $("#graph_datetool .datechoice").removeClass("selected");
477
478                 //start here will be in seconds
479                 displayinfo.start = time_windows[$(this).html()];
480                 displayinfo.end = '';
481                 $(this).addClass("selected");
482                 var cdate = new Date();
483                 update_graph_permalink(graphinfo.id, parseInt(cdate.getTime() - displayinfo.start*1000), "", "");
484                 maingraph.ReconGraphRefresh({graphid: graphinfo.id, start: time_windows[$(this).html()], end: '', type: graphinfo.type});
485                 return false;
486         });
487         $('#graph_widgetCalendar').DatePicker({
488                 flat: true,
489                 format: 'Y/m/d',
490                 date: [new Date(), new Date()],
491                 calendars: 3,
492                 mode: 'range',
493                 starts: 1,
494                 onChange: function(formated) {
495                         var dates;
496                         dates = formated[0].split('/');
497                         var start = new Date(dates[0], dates[1]-1, dates[2], 0, 0, 0);
498                         dates = formated[1].split('/');
499                         var end = new Date((new Date(dates[0], dates[1]-1, dates[2], 0, 0, 0)).getTime() + 86400000);
500                         displayinfo.start = start.toUTCString();
501                         displayinfo.end = end.toUTCString();
502                         update_graph_permalink(graphinfo.id, parseInt(start.getTime()), parseInt(end.getTime()), "");
503                         maingraph.ReconGraphRefresh({graphid: graphinfo.id, start: displayinfo.start, end: displayinfo.end, type: graphinfo.type});
504                         $('#graph_datetool .range a.btn-slide').get(0).innerHTML = formated.join(' - ');
505                 }
506         });
507         $(".graphType").change(function(){
508                 graphinfo.type = $(this).val();
509                 update_current_graph(true);
510         });
511         $("#gtool-error").click(function(){
512           $("#gtool-error").fadeOut("slow");
513         });
514         $(".addGuide").click(function() {
515           if(!locked){
516             gtool_add_guide();
517           }
518         });
519
520         $("span.blankGraph").click(function() {
521
522           stop_streaming_graph();
523
524           // current graph is saved, so just give a new one.
525           if(graphinfo.saved) set_current_graph_id('');
526
527           // otherwise make sure the user wants to move on, and if so, give a new graph and orphan the unsaved one.
528           else if(graphinfo.saved!=undefined && graphinfo.saved==false) {
529             confirm("I will forget the current graph.  Are you sure?", function() {
530               set_current_graph_id('');
531             });
532           }
533
534           return false;
535         });
536
537         set_current_graph_id('');
538         maingraph = $('<div></div>').attr("id", "maingraph").ReconGraph({graphid: graphinfo.id, width: 780, height: 400});
539         $("#maingraphHolder").append(maingraph);
540 });
541 </script>
542
543 <div id="graph_datetool">
544         <div class="zoom">
545                 <dl>
546                         <dt>Zoom:</dt>
547                         <dd><a href="#" class="first datechoice">2d</a></dd>
548                         <dd><a href="#" class="datechoice">1w</a></dd>
549                         <dd><a href="#" class="selected datechoice">2w</a></dd>
550                         <dd><a href="#" class="datechoice">4w</a></dd>
551                         <dd><a href="#" class="datechoice">1y</a></dd>
552                 </dl>
553         </div>
554         <div class="range">
555                 <dl>
556                         <dt>Date Range:</dt>
557                         <dd><a href="" class="btn-slide">YYYY/MM/DD - YYYY/MM/DD</a></dd>
558                 </dl>
559         </div>
560 <br/>
561         <div id="graph_widgetCalendar" class="widgetCalendar"></div>
562 </div>
563                        
564 <!-- confirm box -->
565 <div id="confirm" style="display:none">
566         <a href="#" title="Close" class="modalCloseX modalClose">x</a>
567         <div class="header"><span>Confirm</span></div>
568         <p class="message"></p>
569         <div class="buttons">
570                 <div class="no modalClose">No</div><div class="yes">Yes</div>
571         </div>
572 </div>
573
574 <div>
575         <div id="maingraphHolder">
576         </div>
577         <div class='stream-log' style='display:none'></div>
578         <form action="#" name="form4" id="form4" style="margin:1em 0;text-align:center;">
579         <fieldset>
580         <legend style="display:none;">View</legend>
581         <label for="std_view"><input class="graphType" type="radio" name="graphtype" id="std_view" value="standard"/> Standard View</label> &nbsp;&nbsp;&nbsp;
582         </fieldset>
583         </form>
584        
585 </div>
586 <span class="graphStacks"></span>
587 <div><span class="editStacks">Add Stack Set</span></div>
588 <div style="float:right"><span class="addGuide">Add Guide</span></div>
589 <br style="clear:right" />
590 <div class="error"><p class="error" id="gtool-error"></p></div>
591 <table id="gtool">
592         <tr>
593                 <th></th>
594                
595                 <th class="data">Data Points</th>
596                 <th>Stacking</th>
597                 <th>Color</th>
598                 <th>Derivative</th>
599                 <th>Axis</th>
600                 <th></th>
601                 <th></th>
602         </tr>
603         <tbody id="dataPoints">
604         </tbody>
605 </table>
606
607 <div style="display:none">
608 <form id="hiddeneditor">
609         <table>
610         <tbody id="guideeditor">
611         <tr>           
612                 <td><input name="view" type="checkbox" value="1" /></td>
613                 <td class="data datatitle"></td>
614                 <td><div class="colorPicker"><div class="colorSelector"><div style="background-color: #fff"></div></div><div class="colorPickerHolder"></div></div></td>
615                 <td></td>
616                 <td></td>
617                 <td><a href="#" class="deletedatapoint"><span>delete</span></a></td>
618                 <td class="math">math</td>
619         </tr>
620         <tr class="mathbox">
621                 <td colspan="7">
622                 <div>
623                         <label for="math">Display Math</label> <input name="math1" type="text" value="" style="width:380px;" />
624                 </div>
625                 <div>
626                         <label for="math">Percentile</label> <input name="math2" type="text" value="" style="width:380px;" />
627                 </div>
628                 </td>
629         </tr>
630         </tbody>
631         <tbody id="datapointeditor">
632         <tr>
633                 <td><input name="view" type="checkbox" value="1"/></td>
634                 <td class="data datatitle"></td>
635                 <td><select id="datastack" class="av_stacks"><option value='na'>select</option></select></td>
636                 <td><div class="colorPicker"><div class="colorSelector"><div style="background-color: #fff"></div></div><div class="colorPickerHolder"></div></div></td>
637                 <td><select name="derive"><option value="false">no</option><option value="derive">derive</option><option value="counter">counter</option></select></td>
638                 <td><span class="axis axisl"> L</span> <span class="axis axisr"> R</span></td>
639                 <td><a href="#" class="deletedatapoint"><span>delete</span></a></td>
640                 <td class="math">math</td>
641         </tr>
642         <tr class="mathbox">
643                 <td colspan="7">
644                 <div>
645                         <label for="math">Display Math</label> <input name="math1" type="text" value="" style="width:380px;" />
646                 </div>
647                 <div>   
648                         <label for="math">Source Math</label> <input name="math2" type="text" value="" style="width:380px;" />
649                 </div>
650                 </td>
651         </tr>
652         </tbody>
653         </table>
654 </form>
655 </div>
656
657 <div id="payload">
658 </div>
Note: See TracBrowser for help on using the browser.