Dart circumvent dart:io http parsing error - flutter

I am working with a 3rd party device that hosts its own webserver. I am trying to hit this webserver with a get request. It succeeds with curl, or postman, but the get response is interpreted as erroneous from dart:io. This code receives an error: HttpException (HttpException: Failed to parse HTTP, 32 is expected to be a Hex digit, uri = http://10.22.2.214/settings/time)
import 'dart:convert';
import 'dart:io';
Future<void> main(List<String> arguments) async {
var request = await HttpClient().openUrl(
'get',
Uri.parse('http://10.22.2.214/settings/time'),
);
var response = await request.close();
var chunks = [];
var stringStream = response.transform(Utf8Decoder(allowMalformed: true));
// stringStream = stringStream.handleError((e) => null);
await for (var chunk in stringStream) {
chunks.add(chunk);
}
print(chunks);
}
The request succeeds and gives the full expected response in a number of other places. IE: Python 3+(requests), Postman, Curl, Google Chrome. So I know it is possible to parse the request successfully.
Anyone have any ideas on how I might circumvent the error? I would like to stay in dart/flutter if possible. I know I could run python code with a package like starflut, but its a lot of setup for a single request.
Additional Info:
Ignoring the error view the handleError function does not seem to keep the stream open to receive the rest of the response.
The webserver fails to properly implement HTTP 1.1 by incorrectly using the Transfer-Encoding: chunked header.
Http and Dio both use dart:io under the hood and both gave me the same error.
result from curl -D - http:/10.22.2.214/settings/time
HTTP/1.1 200 OK
Content-Type: text/html
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Allow-Headers: *
Connection: close
Accept-Ranges: none
Transfer-Encoding: chunked
<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500">
<meta charset="utf-8"><title>Time Settings</title><script>
var d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings")}function B(){window.open("/settings","_self")}function S(){BTa(),GetV(),Cs(),FC()}function gId(t){return d.getElementById(t)}function Cs(){gId("cac").style.display="none",gId("coc").style.display="block",gId("ccc").style.display="none",gId("ca").selected&&(gId("cac").style.display="block"),gId("cc").selected&&(gId("coc").style.display="none",gId("ccc").style.display="block"),gId("cn").selected&&(gId("coc").style.display="none")}function BTa(){var t="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Preset</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>";for(i=0;i<8;i++)for(t+='<tr><td><input name="W'+i+'" id="W'+i+'" type="number" style="display:none"><input id="W'+i+'0" type="checkbox"></td><td><input name="H'+i+'" type="number" min="0" max="24"></td><td><input name="N'+i+'" type="number" min="0" max="59"></td><td><input name="T'+i+'" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W'+i+j+'" type="checkbox"></td>';for(t+='<tr><td><input name="W8" id="W8" type="number" style="display:none"><input id="W80" type="checkbox"></td><td>Sunrise<input name="H8" value="255" type="hidden"></td><td><input name="N8" type="number" min="-59" max="59"></td><td><input name="T8" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W8'+j+'" type="checkbox"></td>';for(t+='<tr><td><input name="W9" id="W9" type="number" style="display:none"><input id="W90" type="checkbox"></td><td>Sunset<input name="H9" value="255" type="hidden"></td><td><input name="N9" type="number" min="-59" max="59"><td><input name="T9" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W9'+j+'" type="checkbox"></td>';gId("TMT").innerHTML=t}function FC(){for(j=0;j<8;j++)for(i=0;i<10;i++)gId("W"+i+j).checked=gId("W"+i).value>>j&1}function Wd(){for(a=[0,0,0,0,0,0,0,0,0,0],i=0;i<10;i++){for(m=1,j=0;j<8;j++)a[i]+=gId("W"+i+j).checked*m,m*=2;gId("W"+i).value=a[i]}}function addRow(t,e,n,i){var d=gId("macros"),u=d.rows.length,c=d.insertRow(u);document.createElement("td");c.insertCell(0).innerHTML=`Button ${t}:`,c.insertCell(1).innerHTML=`<input name="MP${t}" type="number" min="0" max="250" value="${e}" required>`,c.insertCell(2).innerHTML=`<input name="ML${t}" type="number" min="0" max="250" value="${n}" required>`,c.insertCell(3).innerHTML=`<input name="MD${t}" type="number" min="0" max="250" value="${i}" required>`}function GetV() {
d.Sf.NT.checked=1;d.Sf.NS.value="Ntp-wwv.nist.gov";d.Sf.CF.checked=0;d.Sf.TZ.selectedIndex=6;d.Sf.UO.value=0;d.Sf.LN.value="0.00";d.Sf.LT.value="0.00";d.getElementsByClassName("times")[0].innerHTML="2106-2-7, 12:39:17 AM";d.Sf.OL.selectedIndex=0;d.Sf.O1.value=0;d.Sf.O2.value=0;d.Sf.OM.value=0;d.Sf.OS.checked=0;d.Sf.O5.checked=0;d.Sf.CX.value="HHMMSS";d.Sf.CB.checked=1;d.Sf.CE.checked=0;d.Sf.CY.value=22;d.Sf.CI.value=1;d.Sf.CD.value=1;d.Sf.CH.value=2;d.Sf.CM.value=1;d.Sf.CS.value=1;d.Sf.A0.value=0;d.Sf.A1.value=0;d.Sf.MC.value=0;d.Sf.MN.value=0;addRow(0,0,0,0);addRow(1,0,0,0);addRow(2,0,0,0);addRow(3,0,0,0);d.Sf.H0.value=9;d.Sf.N0.value=24;d.Sf.T0.value=1;d.Sf.W0.value=255;d.Sf.H1.value=9;d.Sf.N1.value=38;d.Sf.T1.value=2;d.Sf.W1.value=255;d.Sf.H2.value=0;d.Sf.N2.value=0;d.Sf.T2.value=0;d.Sf.W2.value=255;d.Sf.H3.value=0;d.Sf.N3.value=0;d.Sf.T3.value=0;d.Sf.W3.value=255;d.Sf.H4.value=0;d.Sf.N4.value=0;d.Sf.T4.value=0;d.Sf.W4.value=255;d.Sf.H5.value=0;d.Sf.N5.value=0;d.Sf.T5.value=0;d.Sf.W5.value=255;d.Sf.H6.value=0;d.Sf.N6.value=0;d.Sf.T6.value=0;d.Sf.W6.value=255;d.Sf.H7.value=0;d.Sf.N7.value=0;d.Sf.T7.value=0;d.Sf.W7.value=255;d.Sf.N8.value=0;d.Sf.T8.value=0;d.Sf.W8.value=0;d.Sf.N9.value=0;d.Sf.T9.value=0;d.Sf.W9.value=0;}</script><style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%;margin:0}hr{border-color:#666}a{color:#28f;text-decoration:none}.btn,button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:12px 8px 8px;padding:1px 6px;cursor:pointer;text-decoration:none}.lnk{border:0}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input:disabled{color:#888}input[type=number]{width:4em;margin:2px}input[type=number].xxl{width:100px}input[type=number].xl{width:85px}input[type=number].l{width:63px}input[type=number].m{width:56px}input[type=number].s{width:49px}input[type=number].xs{width:42px}input[type=checkbox]{transform:scale(1.5);margin-right:10px}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}td{padding:2px}.d5{width:4.5em!important}#toast{opacity:0;background-color:#444;border-radius:5px;bottom:64px;color:#fff;font-size:17px;padding:16px;pointer-events:none;position:fixed;text-align:center;z-index:5;transform:translateX(-50%);max-width:90%;left:50%}#toast.show{opacity:1;background-color:#264;animation:fadein .5s,fadein .5s 2.5s reverse}#toast.error{opacity:1;background-color:#b21;animation:fadein .5s}</style></head><body onload="S()"><form
id="form_s" name="Sf" method="post" onsubmit="Wd()"><div class="helpB"><button
type="button" onclick="H()">?</button></div><button type="button" onclick="B()">
Back</button><button type="submit">Save</button><hr><h2>Time setup</h2>
Get time from NTP server: <input type="checkbox" name="NT"><br><input name="NS"
maxlength="32"><br>Use 24h format: <input type="checkbox" name="CF"><br>
Time zone: <select name="TZ"><option value="0" selected="selected">GMT(UTC)
</option><option value="1">GMT/BST</option><option value="2">CET/CEST</option>
<option value="3">EET/EEST</option><option value="4">US-EST/EDT</option><option
value="5">US-CST/CDT</option><option value="6">US-MST/MDT</option><option
value="7">US-AZ</option><option value="8">US-PST/PDT</option><option value="9">
CST(AWST)</option><option value="10">JST(KST)</option><option value="11">
AEST/AEDT</option><option value="12">NZST/NZDT</option><option value="13">
North Korea</option><option value="14">IST (India)</option><option value="15">
CA-Saskatchewan</option><option value="16">ACST</option><option value="17">
ACST/ACDT</option><option value="18">HST (Hawaii)</option><option value="19">
NOVT (Novosibirsk)</option><option value="20">AKST/AKDT (Anchorage)</option>
<option value="21">MX-CST/CDT</option></select><br>UTC offset: <input name="UO"
type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
Current local time is <span class="times">unknown</span>.<br>Latitude (N):
<input name="LT" type="number" min="-66.6" max="66.6" step="0.01">
Longitude (E): <input name="LN" type="number" min="-180" max="180" step="0.01">
<div id="sun" class="times"></div><h3>Clock</h3>Clock Overlay: <select
name="OL" onchange="Cs()"><option value="0" id="cn" selected="selected">None
</option><option value="1" id="ca">Analog Clock</option><option value="2">
Single Digit Clock</option><option value="3" id="cc">Cronixie Clock</option>
</select><br><div id="coc">First LED: <input name="O1" type="number" min="0"
max="255" required> Last LED: <input name="O2" type="number" min="0" max="255"
required><br><div id="cac">12h LED: <input name="OM" type="number" min="0"
max="255" required><br>Show 5min marks: <input type="checkbox" name="O5"><br>
</div>Seconds (as trail): <input type="checkbox" name="OS"><br></div><div
id="ccc">Cronixie Display: <input name="CX" maxlength="6"><br>
Cronixie Backlight: <input type="checkbox" name="CB"><br></div>Countdown Mode:
<input type="checkbox" name="CE"><br>Countdown Goal:<br>Year: 20 <input
name="CY" type="number" min="0" max="99" required> Month: <input name="CI"
type="number" min="1" max="12" required> Day: <input name="CD" type="number"
min="1" max="31" required><br>Hour: <input name="CH" type="number" min="0"
max="23" required> Minute: <input name="CM" type="number" min="0" max="59"
required> Second: <input name="CS" type="number" min="0" max="59" required><br>
<h3>Macro presets</h3><b>Macros have moved!</b><br><i>
Presets now also can be used as macros to save both JSON and HTTP API commands.
<br>Just enter the preset id below!</i> <i>
Use 0 for the default action instead of a preset</i><br>Alexa On/Off Preset:
<input name="A0" type="number" min="0" max="250" required> <input name="A1"
type="number" min="0" max="250" required><br>Countdown-Over Preset: <input
name="MC" type="number" min="0" max="250" required><br>
Timed-Light-Over Presets: <input name="MN" type="number" min="0" max="250"
required><br><h3>Button actions</h3><table style="margin:0 auto" id="macros">
<thead><tr><td>push<br>switch</td><td>short<br>on->off</td><td>long<br>
off->on</td><td>double<br>N/A</td></tr></thead><tbody></tbody></table><a
href="https://github.com/Aircoookie/WLED/wiki/Macros#analog-button"
target="_blank">Analog Button setup</a><h3>Time-controlled presets</h3><div
style="display:inline-block"><table id="TMT"></table></div><hr><button
type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form></body></html>

Related

Getting a null value of an HTML element within Flutter using queryselector

I am facing a problem while trying to listen to the "onclick" event of an html element.
I have attached the images of my dart code and HTML file I am using.
Its throwing the error
"Error: Expected a value of type 'HtmlElement', but got one of type 'Null'"
Here is the Dart Code where I am trying to get the element by id!
HtmlElementView(
onPlatformViewCreated: (id) {
HtmlElement element = document
.querySelector("#form-checkout__issuer") as HtmlElement;
element.onChange.listen(
(event) {
print("this is the current event: $event");
},
);
Here is the HTML Document I am showing in my Flutter Web App
<!-- <div class = "card"> -->
<form id="form-checkout">
<input type="text" name="cardNumber" id="form-checkout__cardNumber" />
<input type="text" name="expirationDate" id="form-checkout__expirationDate" />
<input type="text" name="cardholderName" id="form-checkout__cardholderName"/>
<input type="email" name="cardholderEmail" id="form-checkout__cardholderEmail"/>
<input type="text" name="securityCode" id="form-checkout__securityCode" />
<select name="issuer" id="form-checkout__issuer"></select>
<select name="identificationType" id="form-checkout__identificationType"></select>
<input type="text" name="identificationNumber" id="form-checkout__identificationNumber"/>
<select name="installments" id="form-checkout__installments"></select>
<button type="submit" id="form-checkout__submit">Pay</button>
<progress value="0" class="progress-bar">Loading...</progress>
</form>
<!-- </div> -->
Here are the In App Code images!

Is it possible to format number in input?

I'm using Thymeleaf. I would like to make a form where numbers are thousand-separated. Here is my code:
<form action="#" id="postForm" th:action="#{/foo/update}"
<!-- other fields -->
<label for="barNumber" form="postForm">Number of bars</label>
<input id="barNumber" type="number" th:field="#numbers.format(*{barNumber}, 3, 'COMMA')" required="required">
</form>
It threw me error. I also tried:
<input id="barNumber" type="number" th:field="${numbers.formatInteger(*{barNumber}, 3, 'COMMA')" required="required">
It was also unsuccessful.
How could I solve this problem?

Salesforce Web-to-Lead form collecting UTM data after browsing multiple pages

I have a salesforce web-to-lead form that is set up to collect utm data, and it does.... if I dont leave the page.
Currently, I am not using sf web to lead form. If the user comes to site from an ad, the utm parameters are stored in a cookie and used if the user completes a form. It works perfectly.
I now am required to use sf web to lead forms. If I land directly on the page and never leave, the utm parameters in url are successfully collected in the form. If I leave page and return to form page, I can see the utm parameters stored in the cookie, but the form does not collect.
Please send help!!!!! I need to be able to navigate away from page and use stored cookie to populate the utm hidden form fields.
<form id="salesforceForm" method="POST" action="https://webto.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8">
<input name="oid" type="hidden" value="mySFID#">
<input name="retURL" type="hidden" value="myredirectlink.com">
<label for="first_name">First Name*</label> <input id="first_name" maxlength="40" name="first_name" required="" size="20" type="text">
<label for="last_name">Last Name*</label> <input id="last_name" maxlength="80" name="last_name" required="" size="20" type="text">
<label for="email">Email*</label> <input id="email" maxlength="80" name="email" required="" size="20" type="text">
<label for="company">Company*</label> <input id="company" maxlength="40" name="company" required="" size="20" type="text"> <label for="phone">Phone*</label> <input id="phone" maxlength="40" name="phone" required="" size="20" type="text">
<input id="utm_source" name="00N50000003KWmr" type="hidden" value="">
<input id="utm_medium" name="00N50000003KWn6" type="hidden" value="">
<input id="utm_campaign" name="00N50000003KWnB" type="hidden" value="">
<input id="utm_term" name="00N50000003KWnG" type="hidden" value="">
<input id="utm_content" name="00N50000003KWnL" type="hidden" value="">
<input name="btnSubmit" type="submit">
</form>
<script type="text/javascript">
function parseGET(param) {
var searchStr = document.location.search;
try {
var match = searchStr.match('[?&]' + param + '=([^&]+)');
if (match) {
var result = match[1];
result = result.replace(/\+/g, '%20');
result = decodeURIComponent(result);
return result;
} else {
return '';
}
} catch (e) {
return '';
}
}
document.getElementById('utm_source').value = parseGET('utm_source');
document.getElementById('utm_medium').value = parseGET('utm_medium');
document.getElementById('utm_campaign').value = parseGET('utm_campaign');
document.getElementById('utm_term').value = parseGET('utm_term');
document.getElementById('utm_content').value = parseGET('utm_content');
</script>
There's nothing here that actually sets the cookie, right? Or reads from it.
I've never actively used Google Tag Manager and you're saying something sets the cookie already...
My gut feel you need something like if(parseGET('utm_source') == ""), then use functions from https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie
This helps?
let utm_source = parseGET('utm_source');
if(!utm_source){
utm_source = document.cookie
.split('; ')
.find(row => row.startsWith('utm_source='))
.split('=')[1];
}
document.getElementById('utm_source').value = utm_source;
?
Untested, you'll have to experiment and put right names of cookies.

How to pass data from using POST/form leaf template?

I have a couple of major gaps in my understanding of vapor/leaf/html. I am working from the "todo" example that is created using the beta branch of vapor.
First, I made my own fluent model (no problems that I know of):
import FluentSQLite
import Vapor
final class affordatmodel: SQLiteModel {
var id: Int?
var propertyCost: String
var targetEquity: String
var interestRate: String
var amortization: String
var sponsor1: String
var sponsor2: String
var rent: String
var rentInflation: String
var propertyTaxes: String
var propertyTaxesInflation: String
var strataFees: String
var strataFeesInflation: String
init(propertyCost: String, targetEquity: String, interestRate: String, amortization: String, sponsor1: String, sponsor2: String, rent: String, rentInflation: String, propertyTaxes: String, propertyTaxesInflation: String, strataFees: String, strataFeesInflation: String) {
self.propertyCost = propertyCost
self.targetEquity = targetEquity
self.interestRate = interestRate
self.amortization = amortization
self.sponsor1 = sponsor1
self.sponsor2 = sponsor2
self.rent = rent
self.rentInflation = rentInflation
self.propertyTaxes = propertyTaxes
self.propertyTaxesInflation = propertyTaxesInflation
self.strataFees = strataFees
self.strataFeesInflation = strataFeesInflation
}
}
/// Allows to be used as a dynamic migration.
extension affordatmodel: Migration { }
/// Allows to be encoded to and decoded from HTTP messages.
extension affordatmodel: Content { }
/// Allows to be used as a dynamic parameter in route definitions.
extension affordatmodel: Parameter { }
Then I make an instance and send it to a leaf template:
let defaultData = affordatmodel(propertyCost: "700000", targetEquity: "300000", interestRate: "1", amortization: "20", sponsor1: "500000", sponsor2: "200000", rent: "1200", rentInflation: "1", propertyTaxes: "8000", propertyTaxesInflation: "1", strataFees: "0", strataFeesInflation: "0")
return leaf.render("welcome", ["affordat": defaultData])
And my Leaf template successfully populates the html with the default data (body shown here):
<body class="container">
<h1>Payment and Principal Calculations</h1>
<form action="/affordat" method="POST">
<div class="form-group">
<label for="propertyCost">Property Cost</label>
<input type="number" class="form-control" name="propertyCost" placeholder="#(affordat.propertyCost)">
</div>
<div class="form-group">
<label for="targetEquity">Target Equity</label>
<input type="number" class="form-control" name="targetEquity" placeholder="#(affordat.targetEquity)">
</div>
<div class="form-group">
<label for="interestRate">Interest Rate</label>
<input type="number" class="form-control" name="interestRate" placeholder="#(affordat.interestRate)">
</div>
<div class="form-group">
<label for="amortization">Amortization (years)</label>
<input type="number" class="form-control" name="amortization" placeholder="#(affordat.amortization)">
</div>
<div class="form-group">
<label for="sponsor1">Sponsor 1 Funds</label>
<input type="number" class="form-control" name="sponsor1" placeholder="#(affordat.sponsor1)">
</div>
<div class="form-group">
<label for="sponsor2">Sponsor 2 Funds</label>
<input type="number" class="form-control" name="sponsor2" placeholder="#(affordat.sponsor2)">
</div>
<div class="form-group">
<label for="rent">Rent</label>
<input type="number" class="form-control" name="rent" placeholder="#(affordat.rent)">
</div>
<div class="form-group">
<label for="rentInflation">Rent Inflation (will be used exactly)</label>
<input type="number" class="form-control" name="rentInflation" placeholder="#(affordat.rentInflation)">
</div>
<div class="form-group">
<label for="propertyTaxes">Property Taxes (first year est.)</label>
<input type="number" class="form-control" name="propertyTaxes" placeholder="#(affordat.propertyTaxes)">
</div>
<div class="form-group">
<label for="propertyTaxesInflation">Property Taxes Inflation (est.)</label>
<input type="number" class="form-control" name="propertyTaxesInflation" placeholder="#(affordat.propertyTaxesInflation)">
</div>
<div class="form-group">
<label for="strataFees">Strata Fees (first year est.)</label>
<input type="number" class="form-control" name="strataFees" placeholder="#(affordat.strataFees)">
</div>
<div class="form-group">
<label for="strataFeesInflation">Strata Fees Inflation (est.)</label>
<input type="number" class="form-control" name="strataFeesInflation" placeholder="#(affordat.strataFeesInflation)">
</div>
<input type="hidden" name="_csrf" value="{{csrfToken}}">
<button type="submit" class="btn btn-primary">Refresh Calculations</button>
</form>
</body>
Great, so I know how to get fluent data to HTML. My problem is I don't know how to get it back. When the "Post" occurs, the data does not seem to get passed to the controller. My route is:
router.post("affordat", use: affordatController.create)
And the relevant part of my controller looks like this:
import Vapor
final class AffordatController {
func create(_ req: Request) throws -> Future<affordatmodel> {
return try req.content.decode(affordatmodel.self).flatMap(to: affordatmodel.self) { affordatmodel1 in
return affordatmodel1.save(on: req)
}
}
}
Which shows me one of my models, with an ID #, but no data. And I kind of understand why because I didn't really seem to send the post data to the controller. How I am supposed to send the POST data to the controller? Is the problem in my leaf template, my route, or my controller?
It looks like it should work. You can inspect the data being sent to your server in the network inspector in your browser. Make sure you preserve logs and you'll be able to see the POST request and the data sent to the server.
If you breakpoint at each point in the request you can see what the data is.
As an aside, it looks like you're submitting an empty form, so it's just filling everything in as blank strings. Do you mean to use value instead of placeholder in the form inputs? Value will pre-populate the data for the user, placeholder will show the value to the user as a suggestion but won't send the data in the form submission.

How do I automatically insert a default value into a textarea if no value was entered in by a user?

I have a form with a few textareas in it and I need to figure out a way to automatically insert the word "null" as the textarea values if a user chooses not to include any data in the textarea fields. I would greatly appreciate any one who would be willing to help me out with this. Thank you!
Here's a copy of the code:
<?php
$title = "Add a New Page";
$url = "add";
$metadescription = "Create and publish a new page";
include('/templates/head.php');
echo ('<title>'.$title.'</title>
<meta name="description" content="'.$metadescription.'" />');
include('/templates/meta.php');
echo ('<div id="content">');
include('/page-creator.php');
?>
<h2>Add a New Page</h2>
<form method="post" action="#">
<input type="hidden" name="url" value="null">
<input type="hidden" name="commentform" value="yes">
<h3>Author and Page Information (Required):</h3>
<p><strong>Author Name</strong>: <input style="width:250px;" type="text" name="authorname" value="null"></p>
<hr>
<p><strong>Author URL</strong>: <input style="width:250px;" type="text" name="authorurl" value="null"></p>
<hr>
<p><strong>Page Title</strong>: <input style="width:250px;" type="text" name="title" value="null"></p>
<hr>
<p><strong>Page Date</strong>: <input style="width:250px;" type="text" name="pagedate" value="<?php echo date('D, M d Y, g:ia T'); ?>"></p>
<hr>
<p><strong>Brief Description</strong>: One or two sentences.<br/><br/>
<textarea style="width:95%; height:50px;" name="metadescription">null</textarea></p>
<hr>
<h3>Top Section (Required):</h3>
<p><strong>TOP SECTION CONTENT</strong>: In plain text format (NO HTML) describe the details.<br/><br/>
<textarea style="width:95%; height:100px;" name="topsectioncontent"></textarea></p>
<hr>
<p><strong>TOP SECTION IMAGE</strong>: <input style="width:250px;" type="text" name="topsectionimage"></p>
<hr>
<p><strong>TOP SECTION CODE</strong>: Enter css, html, php or other scripting code.<br/><br/>
<textarea style="width:95%; height:100px;" name="topsectioncode">null</textarea></p>
<hr>
<h3>Middle Section (Optional):</h3>
<p><strong>MIDDLE SECTION CONTENT</strong>: In plain text format (NO HTML) describe the details.<br/><br/>
<textarea style="width:95%; height:100px;" name="middlesectioncontent">null</textarea></p>
<hr>
<p><strong>MIDDLE SECTION IMAGE</strong>: <input style="width:250px;" type="text" name="middlesectionimage" value="null"></p>
<hr>
<p><strong>MIDDLE SECTION CODE</strong>: Enter css, html, php or other scripting code.<br/><br/>
<textarea style="width:95%; height:100px;" name="middlesectioncode">null</textarea></p>
<hr>
<h3>Bottom Section (Optional):</h3>
<p><strong>BOTTOM SECTION CONTENT</strong>: In plain text format (NO HTML) describe the details.<br/><br/>
<textarea style="width:95%; height:100px;" name="bottomsectioncontent">null</textarea></p>
<hr>
<p><strong>BOTTOM SECTION IMAGE</strong>: <input style="width:250px;" type="text" name="bottomsectionimage" value="null"></p>
<hr>
<p><strong>BOTTOM SECTION CODE</strong>: Enter css, html, php or other scripting code.<br/><br/>
<textarea style="width:95%; height:100px;" name="bottomsectioncode">null</textarea></p>
<hr>
<h3>Credits and Footnotes (Optional):</h3>
<p><strong>Ref #1 Name:</strong>: <input style="width:250px;" type="text" name="ref01name" value="null"></p>
<p><strong>Ref #1 URL:</strong>: <input style="width:250px;" type="text" name="ref01url" value="null"></p>
<hr>
<p><strong>Ref #2 Name:</strong>: <input style="width:250px;" type="text" name="ref02name" value="null"></p>
<p><strong>Ref #2 URL:</strong>: <input style="width:250px;" type="text" name="ref02url" value="null"></p>
<hr>
<p><strong>Ref #3 Name:</strong>: <input style="width:250px;" type="text" name="ref03name" value="null"></p>
<p><strong>Ref #3 URL:</strong>: <input style="width:250px;" type="text" name="ref03url" value="null"></p>
<hr>
<input type="submit" value="Publish">
</form>
<?php
include('/templates/footer.php'); ?>
Use a shorthand if:
var myValue = myText.value ? myText.value : 'null';
This is, essentially:
var myValue = function() {
if (myText.value) {
return myText.value;
} else {
return 'null';
}
}
With that said, I don't feel you should include this logic on the client. It may be best if whatever you're sending these values handle this scenario, if you have control over it.
So if you are using jQuery then you would do something like this when they click on the submit button, the return true is there so that it will continue with the submit after this function is run.
$(function() {
$('#submitButton').click(function() {
$('textarea').each(function(element) {
if ($(this).text() === '') {
$(this).text('null');
}
});
return true;
});
});
​
I have a JSFiddle that you can try to see what it does.
JSFiddle
I assume you don't want the word 'null' appearing in the UI. I am also assuming that you are handling the returned values in some sort of server-side script.
Be that the case, I would simply test the length of the values stored in the textareas, and if the length is zero (and remember to check for entered spaces etc. using TRIMs and string cleaning routines) I would simply do (pseudo code):
if (mytextarea1.text.length == 0)mytextarea1.text='null'
if (mytextarea2.text.length == 0)mytextarea2.text='null'
etc.