329329 }
330330}
331331 </ style >
332- </ head >
333- < body >
334- < header class ="sticky-header ">
335- < div class ="container header-content navbar ">
336-
337- <!-- Left: Logo -->
338- < a href ="/ " class ="logo ">
339- < img src ="/images/logo.png " alt ="AgriTech Logo ">
340- < span class ="logo-text "> AgriTech</ span >
341- </ a >
342-
343- <!-- Center: Navigation -->
344- < nav class ="nav-links ">
345- < a href ="/index.html "> Home</ a >
346- < a href ="/about.html "> About</ a >
347- < a href ="/blog.html "> Blog</ a >
348- < a href ="/community_forum.html "> Community Forum</ a >
349- < a href ="/faq.html "> FAQ</ a >
350- < a href ="/news.html "> News</ a >
351- </ nav >
352-
353- <!-- Animated Sun/Moon Toggle -->
354- < button class ="theme-toggle " type ="button " id ="themeToggle " title ="Switch to dark mode "
355- aria-label ="Switch to dark mode ">
356- < svg class ="theme-icon " viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 " stroke-linecap ="round "
357- stroke-linejoin ="round ">
358- < mask id ="moon-mask ">
359- < rect x ="0 " y ="0 " width ="100% " height ="100% " fill ="white " />
360- < circle class ="moon-bite " cx ="14 " cy ="9 " r ="14 " fill ="black " />
361- </ mask >
362- < circle class ="sun-core " cx ="12 " cy ="12 " r ="7 " fill ="currentColor " mask ="url(#moon-mask) " />
363- < g class ="sun-rays " stroke ="currentColor ">
364- < line x1 ="12 " y1 ="1 " x2 ="12 " y2 ="3 " />
365- < line x1 ="12 " y1 ="21 " x2 ="12 " y2 ="23 " />
366- < line x1 ="4.22 " y1 ="4.22 " x2 ="5.64 " y2 ="5.64 " />
367- < line x1 ="18.36 " y1 ="18.36 " x2 ="19.78 " y2 ="19.78 " />
368- < line x1 ="1 " y1 ="12 " x2 ="3 " y2 ="12 " />
369- < line x1 ="21 " y1 ="12 " x2 ="23 " y2 ="12 " />
370- < line x1 ="4.22 " y1 ="19.78 " x2 ="5.64 " y2 ="18.36 " />
371- < line x1 ="18.36 " y1 ="5.64 " x2 ="19.78 " y2 ="4.22 " />
372- </ g >
373- </ svg >
374- </ button >
375-
376- </ div >
377- </ header >
378-
379-
380- < main class ="main-layout container ">
381- < div class ="content-left ">
382-
383- < div class ="header ">
384- < h1 > Optimal Crop yield prediction 🎯</ h1 >
385- < p >
386- Based on your provided soil and climate data, the following crop is
387- highly recommended for maximum yield and sustainability.
388- </ p >
389- </ div >
390-
391- html::-webkit-scrollbar-thumb:hover {
392- background: #94ffab;
393- }
394-
395- /* ================= RESPONSIVE ================= */
396- @media (max-width: 1024px) {
397- .main-layout {
398- grid-template-columns: 1fr;
399- }
400- }
401-
402- @media (max-width: 600px) {
403- h1 {
404- font-size: 1.5rem;
405- }
406-
407- .result-value {
408- font-size: 1.8rem;
409- }
410-
411- .action-buttons-group {
412- flex-direction: column;
413- }
414-
415- .nav-links {
416- display: none;
417- }
418- }
419- </ style >
420332</ head >
421333
422- < body >
334+ < body
335+ data-crop ="{{ crop|default('') }} "
336+ data-n ="{{ params.N|default('') }} "
337+ data-p ="{{ params.P|default('') }} "
338+ data-k ="{{ params.K|default('') }} "
339+ data-temperature ="{{ params.temperature|default('') }} "
340+ data-rainfall ="{{ params.rainfall|default('') }} "
341+ data-humidity ="{{ params.humidity|default('') }} "
342+ data-ph ="{{ params.ph|default('') }} "
343+ >
423344 < header class ="sticky-header ">
424345 < div class ="container header-content navbar ">
425346
@@ -482,7 +403,7 @@ <h1>Optimal Crop yield prediction 🎯</h1>
482403 < div class ="result-value ">
483404 < i class ="fas fa-seedling "> </ i >
484405 < span class ="recommended-crop ">
485- < h1 id ="predictedCrop "> Crop Result</ h1 >
406+ < h2 id ="predictedCrop "> Crop Result</ h2 >
486407 </ span >
487408 </ div >
488409 < p class ="insight-note ">
@@ -506,11 +427,7 @@ <h1 id="predictedCrop">Crop Result</h1>
506427 </ div >
507428
508429 < div class ="action-buttons-group ">
509- < form method ="post " action ="/download_report ">
510-
511- < input type ="hidden " name ="{{ key }} " value ="{{ value }} " />
512-
513- < input type ="hidden " name ="crop " value ="{{ crop }} " />
430+ < form method ="post " action ="/download_report " id ="downloadReportForm ">
514431
515432 < button type ="submit " class ="btn btn-primary "
516433 onclick ="this.classList.add('loading'); this.innerHTML='<i class=\'fas fa-spinner fa-spin\'></i> Generating PDF...'; ">
@@ -710,42 +627,124 @@ <h4>Quick Links</h4>
710627 animateCursor ( ) ;
711628 </ script >
712629 < script >
713- /*
714- Frontend-only replacement for Jinja placeholders
715- Reads values from URL query params
716- Example URL:
717- result.html?crop=Wheat&temperature=25&humidity=60&rainfall=120&ph=6.5&N=90&P=40&K=50
718- */
719-
720- function getParam ( name ) {
721- const urlParams = new URLSearchParams ( window . location . search ) ;
722- return urlParams . get ( name ) ;
723- }
630+ ( function ( ) {
631+ function isTemplateToken ( value ) {
632+ return typeof value === "string" && value . includes ( "{{" ) && value . includes ( "}}" ) ;
633+ }
634+
635+ function cleanValue ( value ) {
636+ if ( value === null || value === undefined ) return "" ;
637+ const text = String ( value ) . trim ( ) ;
638+ return isTemplateToken ( text ) ? "" : text ;
639+ }
640+
641+ function getParamInsensitive ( name ) {
642+ const params = new URLSearchParams ( window . location . search ) ;
643+ const target = String ( name ) . toLowerCase ( ) ;
644+ for ( const [ key , value ] of params . entries ( ) ) {
645+ if ( String ( key ) . toLowerCase ( ) === target ) {
646+ return cleanValue ( value ) ;
647+ }
648+ }
649+ return "" ;
650+ }
651+
652+ function getBodyData ( name ) {
653+ const value = document . body && document . body . dataset ? document . body . dataset [ name ] : "" ;
654+ return cleanValue ( value ) ;
655+ }
724656
725- // Set dynamic values
726- document . getElementById ( "predictedCrop" ) . textContent =
727- ( getParam ( "crop" ) || "Recommended Crop" ) . toUpperCase ( ) ;
657+ function resolveValue ( options ) {
658+ const keys = options . queryKeys || [ ] ;
659+ for ( const key of keys ) {
660+ const queryValue = getParamInsensitive ( key ) ;
661+ if ( queryValue ) return queryValue ;
662+ }
728663
729- document . getElementById ( "temperatureValue" ) . textContent =
730- getParam ( "temperature" ) || "--" ;
664+ if ( options . bodyKey ) {
665+ const bodyValue = getBodyData ( options . bodyKey ) ;
666+ if ( bodyValue ) return bodyValue ;
667+ }
731668
732- document . getElementById ( "humidityValue" ) . textContent =
733- getParam ( "humidity" ) || "--" ;
669+ return options . fallback || "--" ;
670+ }
734671
735- document . getElementById ( "rainfallValue" ) . textContent =
736- getParam ( "rainfall" ) || "--" ;
672+ function toTitleCase ( text ) {
673+ return String ( text || "" )
674+ . toLowerCase ( )
675+ . replace ( / \b \w / g, function ( match ) { return match . toUpperCase ( ) ; } ) ;
676+ }
737677
738- document . getElementById ( "phValue" ) . textContent =
739- getParam ( "ph" ) || "--" ;
678+ const resolved = {
679+ crop : resolveValue ( { queryKeys : [ "crop" , "Crop" ] , bodyKey : "crop" , fallback : "Recommended Crop" } ) ,
680+ temperature : resolveValue ( { queryKeys : [ "temperature" , "temp" ] , bodyKey : "temperature" } ) ,
681+ humidity : resolveValue ( { queryKeys : [ "humidity" ] , bodyKey : "humidity" } ) ,
682+ rainfall : resolveValue ( { queryKeys : [ "rainfall" ] , bodyKey : "rainfall" } ) ,
683+ ph : resolveValue ( { queryKeys : [ "ph" , "pH" ] , bodyKey : "ph" } ) ,
684+ N : resolveValue ( { queryKeys : [ "N" , "n" ] , bodyKey : "n" } ) ,
685+ P : resolveValue ( { queryKeys : [ "P" , "p" ] , bodyKey : "p" } ) ,
686+ K : resolveValue ( { queryKeys : [ "K" , "k" ] , bodyKey : "k" } )
687+ } ;
688+
689+ document . getElementById ( "predictedCrop" ) . textContent = toTitleCase ( resolved . crop ) ;
690+ document . getElementById ( "temperatureValue" ) . textContent = resolved . temperature ;
691+ document . getElementById ( "humidityValue" ) . textContent = resolved . humidity ;
692+ document . getElementById ( "rainfallValue" ) . textContent = resolved . rainfall ;
693+ document . getElementById ( "phValue" ) . textContent = resolved . ph ;
694+ document . getElementById ( "nValue" ) . textContent = resolved . N ;
695+ document . getElementById ( "pValue" ) . textContent = resolved . P ;
696+ document . getElementById ( "kValue" ) . textContent = resolved . K ;
697+
698+ const placeholderValueMap = {
699+ Crop : toTitleCase ( resolved . crop ) ,
700+ "params.N" : resolved . N ,
701+ "params.P" : resolved . P ,
702+ "params.K" : resolved . K ,
703+ "params.temperature" : resolved . temperature ,
704+ "params.rainfall" : resolved . rainfall ,
705+ "params.humidity" : resolved . humidity ,
706+ "params.ph" : resolved . ph
707+ } ;
708+
709+ function replaceTemplateTokens ( text ) {
710+ if ( ! text || text . indexOf ( "{{" ) === - 1 ) return text ;
711+
712+ return text
713+ . replace ( / \{ \{ \s * C r o p \s * \| \s * c a p i t a l i z e \s * \} \} / gi, placeholderValueMap . Crop )
714+ . replace ( / \{ \{ \s * p a r a m s \. ( N | P | K | t e m p e r a t u r e | r a i n f a l l | h u m i d i t y | p h ) \s * \} \} / g, function ( _ , key ) {
715+ return placeholderValueMap [ "params." + key ] || "--" ;
716+ } ) ;
717+ }
740718
741- document . getElementById ( "nValue" ) . textContent =
742- getParam ( "N" ) || "--" ;
719+ const walker = document . createTreeWalker ( document . body , NodeFilter . SHOW_TEXT , null ) ;
720+ let textNode = walker . nextNode ( ) ;
721+ while ( textNode ) {
722+ textNode . nodeValue = replaceTemplateTokens ( textNode . nodeValue ) ;
723+ textNode = walker . nextNode ( ) ;
724+ }
743725
744- document . getElementById ( "pValue" ) . textContent =
745- getParam ( "P" ) || "--" ;
726+ document . querySelectorAll ( "[value], [title], [placeholder]" ) . forEach ( function ( element ) {
727+ [ "value" , "title" , "placeholder" ] . forEach ( function ( attr ) {
728+ const existing = element . getAttribute ( attr ) ;
729+ if ( existing && existing . indexOf ( "{{" ) !== - 1 ) {
730+ element . setAttribute ( attr , replaceTemplateTokens ( existing ) ) ;
731+ }
732+ } ) ;
733+ } ) ;
746734
747- document . getElementById ( "kValue" ) . textContent =
748- getParam ( "K" ) || "--" ;
735+ const downloadForm = document . getElementById ( "downloadReportForm" ) ;
736+ if ( downloadForm ) {
737+ [ "crop" , "temperature" , "humidity" , "rainfall" , "ph" , "N" , "P" , "K" ] . forEach ( function ( key ) {
738+ const value = resolved [ key ] ;
739+ if ( ! value || value === "--" ) return ;
740+ const input = document . createElement ( "input" ) ;
741+ input . type = "hidden" ;
742+ input . name = key ;
743+ input . value = value ;
744+ downloadForm . appendChild ( input ) ;
745+ } ) ;
746+ }
747+ } ) ( ) ;
749748 </ script >
750749
751750</ body >
0 commit comments