I am looking for a solution to add "optional chaining" on PugJS to set data-active="true" if i === 0.
Bellow is my current code. This code is working, but the problem with this approach (bellow) is that I have to repeat my code on a else statement and that doesn't make sense. I have to add (i === 0 ? 'data-active="true"' : '') on the .my__element, but I don't know how to do it.
if (i === 0)
.my__element(data-month=months[month] data-active="true")
else
.my__element(data-month=months[month])
Any help please? Thank you
Attribute values in Pug are "just regular JavaScript," as mentioned on the Attributes page on Pug docs.
If an attribute's value is false, Pug doesn't print the attribute at all. This can be seen in the Boolean Attributes section on the same page:
// Input (Pug):
input(type='checkbox' checked)
input(type='checkbox' checked=true)
input(type='checkbox' checked=false)
input(type='checkbox' checked="true")
// Output (HTML):
<input type="checkbox" checked="checked" />
<input type="checkbox" checked="checked" />
<input type="checkbox" />
<input type="checkbox" checked="true" />
So, you can use i === 0 && "true" as the value for the data-active attribute:
.my__element(data-month=months[month] data-active=(i === 0 && "true"))
The parentheses around the attribute's value are optional, but they improve readability. So this is OK but less readable:
.my__element(data-month=months[month] data-active=i === 0 && "true")
A more verbose alternative:
.my__element(data-month=months[month] data-active=(i === 0 ? "true" : false))
.my__element(data-month=months[month] data-active=i === 0 ? "true" : false)
(Note that "true" is a string and false is a boolean; this is on purpose. You can try to switch their types to see why.)
Related
I am new to coldfusion ,
please check my code below
<cfif isDefined("form.submit")>
<cfoutput>
<h3>hi</h3>
</cfoutput>
</cfif>
<cfform action="#CGI.SCRIPT_NAME#">
User Name:<cfinput type="Text" name="usr_nm"><br>
<cfinput type="Radio" name="access_flg" value="0">Admin
<cfinput type="Radio" name="access_flg" value="1">User</br>
<cfinput type="submit" name="submit" value="submit"><br>
</cfform>
But ,When I am clicking submit button ,I am expecting result as hi
I haven't see hi message, Is there any thing wrong in my code ,Any one please help me
Since you're new to ColdFusion, I'll give you some advice straight away:
1. Do not submit a form to the same page.
Submit the form to a separate page for processing. Reason being, as you get into more advanced applications, you'll need to restrict pages/URLs to only respond to an appropriate HTML Verb.
Your form page should respond to HTTP GET.
Your form processing page should only respond to HTTP POST.
2. Do not use CFFORM.
The function of CFFORM is to create JavaScript validation and server-side interactions. This can easily be done with modern JavaScript libraries like
https://jquery.com/
http://jqueryvalidation.org/
3. Give your form elements an ID, as well as a NAME.
This allows easier reference to the form elements when using JavaScript.
4. Do not name your submit button "submit".
If you ever want to use JavaScript to submit a form, the function is submit().
For example: $('#myForm').submit();
Having a form element named the same as a function will cause errors.
Here's my_form.cfm:
<form id="myForm" name="myForm" action="my_form_action.cfm" method="post">
User Name:<input type="Text" id="usr_nm" name="usr_nm"><br>
<input type="Radio" id="access_flg_0" name="access_flg" value="0">Admin
<input type="Radio" id="access_flg_1" name="access_flg" value="1">User</br>
<input type="submit" id="my_form_submit" name="my_form_submit" value="Submit"><br>
</form>
5. You don't need to use CFOUTPUT unless you are rendering data from the server.
Here's my_form_action.cfm:
<cfif structKeyExists(form, "my_form_submit")>
<h3>Hi!<lt>
</cfif>
Even better:
<cfif (cgi.request_method IS "post") AND (structKeyExists(form, "my_form_submit"))>
<h3>Hi!<lt>
</cfif>
This is an elaboration of this part of Adrian's answer:
<cfif (cgi.request_method IS "post") AND (structKeyExists form, "my_form_submit"))>
<h3>Hi!</h3>
</cfif>
This is a candidate for code re-use. In one of our applications, I wrote a custom tag that does something like this:
if (StructKeyExists(attributes, 'ScopeToCheck') is false)
attributes.ScopeToCheck = "form";
if (StructKeyExists(caller, attributes.ScopeToCheck) is false)
Redirect = true;
else if (StructIsEmpty(caller[attributes.ScopeToCheck]) is true)
Redirect = true;
else
Redirect = false;
if (Redirect == true)
location(somewhere, false);
The custom tag approach was appropriate for my situation. For other situations, the same logic can be put into a udf that returns either true or false. Then the calling page can decide what to do with that information.
I have password and repeat password fields,But I want to validate passwords depending on validate regex pattern along with matching both the password fields too.
<p:outputLabel for="Password" value="Password" />
<p:password id="Password" redisplay="true"
value="#{newUserBean.newUserDTO.password}" match="RepeatPassword"
label="Password" required="true"
requiredMessage="Password is required, cannot be empty"
validatorMessage="Password and Repeat Password fields must be same" feedback="true"
promptLabel="Password should contain atleast 8 characters ,1 number and 1 special character" >
</p:password>
<p:outputLabel for="RepeatPassword" value="Repeat Password" />
<p:password id="RepeatPassword" redisplay="true"
value="#{newUserBean.newUserDTO.password}" label="RepeatPassword"
required="true"
requiredMessage="Password is required, cannot be empty" feedback="true"
promptLabel="Repeat Password should match with Password">
</p:password>
Make changes as below
<p:outputLabel for="Password" value="Password" />
<p:password id="Password" redisplay="true"
value="#{newUserBean.newUserDTO.password}"validator="#{passwordValidator.validate}"
label="Password" required="true"
requiredMessage="Password is required, cannot be empty"
validatorMessage="Password and Repeat Password fields must be same" feedback="true"
promptLabel="Password should contain atleast 8 characters ,1 number and 1 special character" >
<p:ajax event="blur" update="msgfrpassword" />
</p:password>
<p:outputLabel for="RepeatPassword" value="Repeat Password" />
<p:password id="RepeatPassword" redisplay="true"
value="#{newUserBean.newUserDTO.password}" label="RepeatPassword" validator="#{confirmPasswordValidator.validate}"
required="true"
requiredMessage="Password is required, cannot be empty" feedback="true"
promptLabel="Repeat Password should match with Password">
<p:ajax event="blur" update="msgfrpassword" />
</p:password>
Override java validator to verify regex and compare repeat password and password
PasswordValidatorBean
#Override
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
matcher = pattern.matcher(value.toString());
if (!matcher.matches()) {
FacesMessage msg = new FacesMessage(
new MessageProvider()
.getValue("prometheus_passwordpromptlable"));
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(msg);
}
}
If we assume you need a regex to be both suitable for running on server and client side, I can suggest this regex that
checks the password length - .{8,}
makes sure there is at least 1 digit - (?=.*[0-9].*$)
and 1 special character (please define what special character means for you, add or remove accordingly) - (?=.*[-+()[\]~!##$%^&*+}{":;'/?.><,\].*$)`
Regex:
^(?=.*[-+()[\]~!##$%^&*+}{":;'/?.><,`\\].*$)(?=.*[0-9].*$).{8,}$
<cfoutput query="allOutcomes" maxrows="10">
<div class="galleryOutcome">
<cfset thisPhoto = uploads.listPhotobyOutcomeID(#outcomeID#)>
<h3>#lastname#, #firstname#</h3>
<cfloop query="thisPhoto" >
<cfif isdefined(filename)>
<div class="gallerythumb">
<img src="documents/uploads/PHOTOS/#filename#" alt="#filename#" border="0" width="200"/>
</div>
<cfelse>
<p> NO PHOTOS </p>
</cfif>
</cfloop>
</div><div class="clear"></div><br /><br />
<div onClick="javascript: thumbHide()" id="thumbexpand" style="display:none; left:670px;; height:0px; position:fixed; top:100px;">
</div>
</cfoutput>
I have been trying to make it so that #lastname# and #firstname# do not display if there are no photos associated to them. I tried doing a cfif that checks to see if the filename is defined, but it didn't seem to work. It returns an error saying:
"Parameter 1 of function IsDefined, which is now (filepath to image), must be a syntactically valid variable name. "
Any tips?
Thanks
First, IsDefined expects the name of a variable. When you omit quotes, or use # signs, you are passing in the variable value instead. The correct syntax is:
<cfif IsDefined("variableName")>
However, query columns always exist. So it will not yield the correct result anyway. Instead you should test if the FileExists. If needed, use expandPath to generate an absolute physical path
<cfif FileExists( ExpandPath("/path/to/images/"& thisPhoto.fileName) )>
it exists. do something ...
<cfelse>
no photo
</cfif>
Edit: As Busches mentioned in the comments, generally structKeyExists is preferred over IsDefined because its results are more precise. Some may argue it also has better performance. But in most cases, any differences are negligible. Increased accuracy is the more compelling reason IMO.
<cfif structKeyExists( scopeOrStruct, "variableName")>
isDefined takes the name of the variable as a string, not the variable itself. change
<cfif isdefined(filename)>
to
<cfif isdefined("filename")>
use <cfif len(filename)>
I guess filename is one of the columns? In a query object, null is represented with empty string, so len() would work.
I have a field that a user can input first and last name to fill out my form. Sometimes, users put on their first name and that results in empty fields in my database. PLEASE keep in mind that I cannot change this method completely because this form is part of a bigger project and it is being used by other websites of my company.
This is the part of the code that i need the validation around it. I already have a validation that ensures that the filed is not empty but I need on more to ensure that the field has two items in it separated by space.
<input name="fullname" class="fullname" type="text" value="#fullname#" maxlength="150"/>
<cfif fullname eq '' and check2 eq 'check2'>
<br /><span style="color:red">*you must enter your full name</span></cfif>
The check2 eq 'check2' is checking if the form was submitted already to ensure a user submitting their data twice.
I thought of using regular expressions to do that but unfortunately I am not very familiar with how to use regx in CF9 and the documentation online through me off a bit.
I was also thinking to use "Find" or "FindOneOF", any thoughts on that?
Also, I am trying to avoid using JQ,JS etc, so please try to keep your suggestions based on CF code IF possible.
Any help or different suggestions on how to tackle this issue will be very appreciated.
No regex is needed for this. A slightly simpler solution:
<cfset form.fullname = "Dave " />
<cfif listLen(form.fullname," ") GT 1> <!--- space-delimited list, no need for trimming or anything --->
<!--- name has more than one 'piece' -- is good --->
<cfelse>
<!--- name has only one 'piece' -- bad --->
</cfif>
You could do something like this for server side validation:
<cfscript>
TheString = "ronger ddd";
TheString = trim(TheString); // get rid of beginning and ending spaces
SpaceAt = reFind(" ", TheString); // find the index of a space
// no space found -- one word
if (SpaceAt == 0) {
FullNameHasSpace = false;
// at least one space was found -- more than one word
} else {
FullNameHasSpace = true;
}
</cfscript>
<cfoutput>
<input type="input" value="#TheString#">
<cfif FullNameHasSpace eq true>
<p>found space at position #SpaceAt#</p>
<p>Your data is good.</p>
<cfelse>
<p>Did not find a space.</p>
<p>Your data is bad.</p>
</cfif>
</cfoutput>
I am using the <cfinput type="datefield"> and I need to limit the dates that can be chosen. I cannot allow a date that can be selected in the past. Any help here?
Thanks!
Well you have two options validating it strictly server side or additionally adding a client side javascript check.
For the serverside, your cfm processing page could use the DateCompare function like so:
<cfif DateCompare(Date1,Date2) EQUAL -1>
<!--- Date 1 < Date 2 --->
<cfelseif DateCompare(Date1,Date2) EQUAL 0>
<!--- Date 1 = Date 2 --->
<cfelseif DateCompare(Date1,Date2) EQUAL 1>
<!--- Date 1 > Date 2 --->
</cfif>
Documentation and sample code is available for this function at:
http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_m-r_11.html
Another post suggested using the range functionality, however I was not able to get this to work because the Adobe documentation said it was only supported on type numeric.
Alternatively you can use javascript to check if the date is within range live on the page:
<html>
<head>
<script type="text/javascript">
function withinRange(submittedDate) {
var start = Date.parse("08/10/2009");
var end = Date.parse("09/11/2009");
var userDate = Date.parse(document.getElementById('leaveDate').value);
var previousDate = document.getElementById('calendarWorkaround').value;
if (!isNaN(userDate) && ( previousDate != userDate)) {
document.getElementById('calendarWorkaround').value = userDate;
if (start <= userDate && end >= userDate) {
alert("Your date is correct!");
} else {
alert("Date is incorrect.");
}
}
}
</script>
</head>
<body>
<cfform name="testing" id="vacationForm"action="testprocess">
<cfinput name="date" type="datefield" id="leaveDate">
<input type="hidden" name="workaround" id="calendarWorkaround" value="-1">
</cfform>
<!--- To get around onChange bug with cfinput type datefield --->
<cfajaxproxy bind="javaScript:withinRange({leaveDate})">
</body>
</html>
Now I would use the onChange attribute for cfinput on the datefield, however there is a bug that it does not call the javascript function that seems to be documented on a couple of other pages online. The workaround that I used was the cfajaxproxy call with the bind attribute. If you are using cfeclipse, it will give you an error that the syntax is not correct however it worked fine for me.
The hidden input type is necessary because with the cfajaxproxy tag, everytime you click the calendar icon it will call the javascript function which is not what we want. So I store the last value chosen by the user (or -1 on page load) so that the javascript to check if it is within range is only executed if the value changes. It is a bit of a hack, however the implementation of <cfinput type="datefield"> does not work as documented.
You can also modify this example so that coldfusion dynamical generates the start date and end date so it is not hard coded.
Just remember that whichever way you choose, you should always check the value server side just in case the user has javascript disabled.
Try this:
Three datefields.
One is hidden by the hieght = 0. It is your starting point. I used today plus one so the user can select today in the Date Requested field.
<cfformgroup type="horizontal" height="0">
<cfinput type="datefield" name="firstAvailableDate" value="#dateAdd('d', +1,now())#"
</cfformgroup>
The requested date will be only today or before.
<cfformgroup type="horizontal">
<cfinput type="datefield" name="request_date" id="request_date" mask="mm/dd/yyyy" width="100" label=”Date Requested” onFocus="request_date.disabledRanges=[{rangeStart:firstAvailableDate.selectedDate}];" />
The Due Date can only be after the requested date selected.
<cfinput type="datefield" name="datedue" id="datedue" mask="mm/dd/yyyy" width="100" label=”Due Date” onFocus="datedue.disabledRanges=[{rangeEnd:request_date.selectedDate}];" />
</cfformgroup type="horizontal" >
AFAIK, there is no easy way to prevent the client from picking a day in the past. We have fields like that on a few of our forms that we check against the current date on the server side, though. Just remember to generate the date without the time for comparison, or you end up with [today's date] < now().
At first, I thought <cfcalendar> would help, but seems like the startrage and endrange is for disabled range.
I guess if you Really want to limit the range, use something else like jQuery UI Datepicker
Through experimentation, I was able to customize the supporting javascript files to restrict the selectable dates. However the jQuery option sounds good as well.
I just added 100 years on to the endrange attribute for the cfcalendar component, thinking no one will sit and click through that far to beat your validation :
<cfset startRange = #dateformat(now(), 'dd/mm/yyyy')# >
<cfset endRange = dateadd("yyyy", 100, #Now()#)>
<cfset selectedDate = dateadd("d", -1, #Now()#)>
<cfcalendar name="start_period" mask="dd/mm/yyyy" selecteddate="#selectedDate#" startRange="#startRange#" endrange="#endRange#">
Simon.
You can't make a datefield limit the dates that can be chosen. CFINPUT doesn't have any attribute to define this type of rule. You have to go for Jquery datepicker. If you want to use cfinput, you can work around that.
<script language="JavaScript">
$(function() {
$( "#date" ).datepicker({
changeMonth: true,
changeYear: true,
minDate: new Date(1939, 10 - 1, 25),
maxDate: '-1D'
});
});
</script>
<cfinput name="date" type="text" size="30" id="date" >
You should use server side validation as well, but I believe you can use the "range" attribute of cfinput to limit the valid dates.