I have set of code for updating a password in the table, here I'm using CGI::AJAX module to update the password and get the popup screen on corresponding execution.When using that code with my application it is executing properly but I didn't get the output(means Perl subroutine is not called when JavaScript function to get use.password is not updated into table). I don't get any error either.
#!/usr/bin/perl -w
use strict;
use CGI;
use DBI;
use Data::Dumper;
my $p = new CGI qw(header start_html end_html h1 script link);
use Class::Accessor;
use CGI::Ajax;
my $create_newuser;
my $ajax = new CGI::Ajax('fetch_javaScript' => $create_newuser);
print $ajax->build_html($p,\&Show_html,{-charset=>'UTF-8', -expires=>'-1d'});
sub Show_html
{
my $html = <<EOHTML;
<html>
<body bgcolor="#D2B9D3">
<IMG src="karvy.jpg" ALT="image">
<form name='myForm'>
<center><table><tr><td>
<div style="width:400px;height:250px;border:3px solid black;">
<center><h4>Create New Password's</h4>
<p>  User Name</b>       <INPUT TYPE="text" NAME="user" id = "user" size = "15" maxlength = "15" tabindex = "1"/></p>
<p>  Password:</b>         <INPUT TYPE=PASSWORD NAME="newpassword" id = "newpassword" size = "15" maxlength = "15" tabindex = "1"/></p>
<p>  Re-Password:</b>   <INPUT TYPE=PASSWORD NAME="repassword" id = "repassword" size = "15" maxlength = "15" tabindex = "1"/></p>
<input type="submit" id="val" value="Submit" align="middle" method="GET" onclick="fetch_javaScript(['user','newpassword','repassword']);"/><INPUT TYPE="reset" name = "Reset" value = "Reset"/>
<p>Main Menu <A HREF = login.pl>click here</A>
</center>
</div>
</td></tr></table></center>
</form>
</body>
</html>
EOHTML
return $html;
}
$create_newuser =sub
{
my #input = $p->params('args');
my $user=$input[0];
my $password=$input[1];
my $repassword=$input[2];
my $DSN = q/dbi:ODBC:SQLSERVER/;
my $uid = q/123/;
my $pwd = q/123/;
my $DRIVER = "Freetds";
my $dbh = DBI->connect($DSN,$uid,$pwd) or die "Coudn't Connect SQL";
if ($user ne '')
{
if($password eq $repassword)
{
my $sth=$dbh->do("insert into rpt_account_information (user_id,username,password,user_status,is_admin) values(2,'".$user."','".$password."',1,1)");
my $value=$sth;
print $value,"\n";
if($value == 1)
{
print 'Your pass has benn changed.Return to the main page';
}
}
else
{
print "<script>alert('Password and Re-Password does not match')</script>";
}
}
else
{
print "<script>alert('Please Enter the User Name')</script>";
}
}
my $create_newuser;
my $ajax = new CGI::Ajax('fetch_javaScript' => $create_newuser);
...;
$create_newuser =sub { ... };
At the moment when you create a new CGI::Ajax object, the $create_newuser variable is still undef. Only much later do you assign a coderef to it.
You can either assign the $create_newuser before you create the CGI::Ajax:
my $create_newuser =sub { ... };
my $ajax = new CGI::Ajax('fetch_javaScript' => $create_newuser);
...;
Or you use a normal, named subroutine and pass a coderef.
my $ajax = new CGI::Ajax('fetch_javaScript' => \&create_newuser);
...;
sub create_newuser { ... }
Aside from this main error, your script has many more problems.
You should use strict instead of the -w option.
For debugging purposes only, use CGI::Carp 'fatalsToBrowser' and sometimes even with warningsToBrowser can be extremely helpful. Otherwise, keeping a close eye on the error logs is a must.
my $p = new CGI qw(header start_html end_html h1 script link) doesn't make any sense. my $p = CGI->new should be sufficient.
use Class::Accessor seems a bit random here.
The HTML in Show_html is careless. First, your heredocs allows variable interpolation and escape codes – it has the semantics of a double quoted string. Most of the time, you don't want that. Start a heredoc like <<'END_OF_HTML' to avoid interpolation etc.
Secondly, look at that tag soup you are producing! Here are some snippets that astonish me:
bgcolor="#D2B9D3", align="middle" – because CSS hasn't been invented yet.
<center> – because CSS hasn't been invented yet, and this element isn't deprecated at all.
<table><tr><td><div ... </div></td></tr></table> – because there is nothing wrong with a table containing a single cell. (For what? This isn't even for layout reasons!) This table cell contains a single div …
… which contains another center. Seriously, what is so great about unneccessary DOM elements that CSS isn't even an option.
style="width:400px;height:250px;border:3px solid black;" – because responsive design hasn't been invented yet.
<p> ... </b> – Oh, what delicious tag soup!
        – this isn't a typewriter, you know. Use CSS and proper markup for your layout. There is a difference between text containing whitespace, and empty areas in your layout.
tabindex = "1" … tabindex = "1" … tabindex = "1" – I don't think you know what tabindex does.
<A HREF = login.pl> – LOWERCASING OR QUOTING YOUR ATTRIBUTES IS FOR THE WEAK!!1
onclick="fetch_javaScript(['user','newpassword','repassword']);" – have you read the CGI::Ajax docs? This is not how it works: You need to define another argument with the ID of the element where the answer HTML is displayed.
In your create_newuser, you have an SQL injection vulnerability. Use placeholders to solve that. Instead of $sth->do("INSERT INTO ... VALUES('$foo')") use $sth->do('INSERT INTO ... VALUES(?)', $foo).
print ... – your Ajax handler shouldn't print output, instead it should return a HTML string, which then gets hooked into the DOM at the place your JS function specified. You want something like
use HTML::Entities;
sub create_newuser {
my ($user, $password, $repassword) = $p->params('args');
my ($e_user, $e_password) = map { encode_entities($_) } $user, $password;
# DON'T DO THIS, it is a joke
return "Hello <em>$e_user</em>, your password <code>$e_password</code> has been successfully transmitted in cleartext!";
}
and in your JS:
fetch_javaScript(['user','newpassword','repassword'], ['answer-element'], 'GET');
where your HTML document somewhere has a <div id="answer-element" />.
Related
Input validation works fine with a fixed pattern, e.g.
<input type="number"
[(ngModel)]="info.sortOrder"
pattern="[0-9][0-9]"
id="sortOrder" name="sortOrder" #sortOrder="ngModel"/>
When changing the pattern to be evaluated through a function, validation always fails. The function "customPattern()" is called, though.
<input type="number"
[(ngModel)]="info.sortOrder"
[pattern]="customPattern()"
id="sortOrder" name="sortOrder" #sortOrder="ngModel"/>
With
customPattern() { return "[1-9][0-9]"; }
Is this a bug or is this not supposed to work this way?
I guess you are dong wrong, #black
I would recommend you to use Reactive Forms approach to achieve the desire result.
create a reactive form.
Add the control name for eg('number_validation').
(optional) Register the HTML input element with the formControlName same as above ('number_validation').
create a field 'regex' = '[0-9][0-9]' in the component.ts file.
Bind the [pattern] = regex in the HTML HTML input element tag.
Listen the change and change the regex pattern according to the requirement.
In ts file.
someForm: FormGroup;
this.someForm= new FormGroup({
'some_name': new FormControl('', [
Validators.required])});
regex = /[0-9][0-9]/;
In HTML:
<input type="number"
[pattern]=regex
id="sortOrder"
formControlName=some_name
name="sortOrder"/>
Logic :
It depends on the requirement how you are going to change the regex value, dynamically.
eg.
ngAfterViewInit() {
this.someForm.get('some_name').valueChanges.subscribe(val => {
if (val === 'anything') {
this.regex = /change the regex/;
} else if (val === 'anything_other') {
this.regex = /change the regex/;
}
});
}
Hope it help you, or other devs! :)
In you component, simply define a member variable like this:
export class AppComponent {
customPattern = '[1-9][0-9]';
In your html, use interpolation like this:
pattern = "{{customPattern}}"
That should work.
I am trying to set up a Kendo MVC Grid using client templates for a set of columns.
I have this and it is working:
columns.Bound(m => m.FC_Sun).ClientTemplate("# if(FC_Sun != Base_Sun) {#" + "<span style='color:red;'>#:FC_Sun # </span>" + "# } else {#" + "#: FC_Sun #" + "# } #");
However I would like to move this to a client template instead as I need to add quite a few more items to the column and an inline template just seems a little 'clunky'.
The question is, how can I do this with a single client template. I have an existing one which works for a particular column (the same one as above).
<script id="columnTemplate" type="text/kendo-tmpl">
#if(FC_Sun != Base_Sun){#
<span style='color:orange'>#:FC_Sun #</span>
#}else{#
<span>#: FC_Sun #</span>
#}#
</script>
As you can see this is very much tied to one column, doing it this way I would need to create 7 templates, one for each day of the week, which just seems overkill.
So is there a way to pass extra parameters to the template which tell it which values to use in the if statement..?
As it turns out there is a way to pass parameters to the template, in the grid:
"#=customColumnTemplate($.extend({}, data, { field: 'FC_Sun' }))#"
And the template:
<script id="columnTemplate" type="text/kendo-tmpl">
<p>#= data[field] #</p>
</script>
<script>
var customColumnTemplate = kendo.template($('#columnTemplate').html());
</script>
The way I actually did it in the end though was to skip the external template and use a function directly:
"#=customColumnTemplate(data, 'FC_Sun', 'Base_Sun')#"
.
function customColumnTemplate(data, field, baseField) {
var fc = data[field];
var fcBase = data[baseField];
if (fc != fcBase) {
return "<span style='color:red;'/>" + fc + "</span>";
}
return fc;
}
There isn't a way to pass parameters directly to a Kendo template, unfortunately. However, you could try using a switch statement in your template, and add an enumeration (or whatever would work) to your model for the switch key:
<script id="columnTemplate" type="text/kendo-tmpl">
# switch (DayofWeek) {
case "Sunday": #
<span style='color:orange;'>#:FC_Sun #</span>
# break; #
# case "Monday": #
<span style='color:red;'>#:FC_Mon #</span>
# break; #
...
# } #
</script>
This should allow you to "pass parameters" via the model, and control the appearance of the template per model instance.
Hope this helps.
I am using code like this to detect the browser and apply a condition to display or not display <label>:
#{
var settings = Model.PartFieldDefinition.Settings.GetModel();
System.Web.HttpBrowserCapabilitiesBase theBrow = Request.Browser;
}
<fieldset>
#{
if ((theBrow.Browser == "IE") && (theBrow.MajorVersion < 10))
{
#:<label>#Model.DisplayName</label>
#://Some Code for inputs
}
else
{
#://Some Code for inputs
}
}
</fieldset>
I have been trying to figure out if I can (and if so, how) I could utilize this logic to detect what path in the website the user is in to display or not display <label>
For example, on any other path I want the label displayed. However, for the pages under ~/Services (the path), I want to be able to hide the label.
It's a little bit more complicated than that. The code is in an editor template that gets used all over the site. If I use CSS in the editor template to "hide" the label I will affect all the pages. I was hoping with the above logic I can avoid that and only apply my logic on certain pages under a path.
Thanks.
Update
I have tried the following:
#{
string CurrentURL = Request.ApplicationPath;
}
<fieldset>
#{
if ((CurrentURL == "Services")) // also tried "/Services"
// rest of code left out for brevity
}
but the labels are hidden on all pages, even outside the path "~/Services". Am stuck on the syntax.
Found answer
I did the following:
#{
string CurrentURL = Request.Url.AbsoluteUri;
}
<fieldset>
#{
if (CurrentURL.Contains("Services"))
}
and it worked. I don't know if anyone can comment, but which would be better to use: Request.Url.AbsoluteUri or Request.Url.ToString() (both of which work)?
I'm trying to do a real simple setup.
1.Do checks on each field using CGI::Ajax.
2.Validate that all fields have been filled in with simple perl CGI
The thing is, when testing individually, both work, but when combined as seen in the code below I have two issues:
1.In the username and password fields I see CGI=HASH(0x228ed48) etc
2. When I push the submit button and there is an error (a field is empty), it prints an internal server error, I believe this is due to $ajx->build_html( $cgi, \&form($error, $username, $password)); and calling the form function in this manner.
Any ideas?
Thanks in advance.
#!/usr/bin/perl -w
use CGI;
use CGI::Session qw/ -ip-match/;
use CGI::Ajax;
$cgi = new CGI;
#$session = new CGI::Session(undef, $cgi, {Directory=> '/tmp'});
my $ajx = new CGI::Ajax( 'checkuser' => \&checkuser );
#print $ajx->build_html( $cgi, \&form);
if($cgi->param("submit")) {
process(); } else { print $ajx->build_html( $cgi, \&form); }
sub checkuser
{
my $input = shift;
my $out = $input . " is not taken";
return $out;
}
sub form {
my $error = shift;
my $username = shift;
my $password = shift;
my $html = <<HTML;
<html>
<BODY>
<form id='log' action='session.cgi' method='post' accept-charset='UTF-8'>
<input type="hidden" name="submit" value="Submit">
<fieldset>
<legend>Login</legend>
<font color="red">$error</font>
<label for='username' >UserName*:</label>
<input type='text' name='user' id='user' value="$username"
maxlength="50" onchange="checkuser( ['user'], ['resultdiv'] );">
<br><br>
<div id="resultdiv"></div>
<label for='password' >Password*:</label>
<input type='password' name='pd' id='pd' value="$password" maxlength="50" />
<input type='submit' name='Submit' value='Submit' />
</fieldset>
</form>
</body></html>
HTML
return $html;
}
sub process
{
if(validate_form()) {
print $cgi->header;
print <<HTML;
<body>Validated<br></body>
HTML
}
}
sub validate_form
{
my $username = $cgi->param("user");
my $password = $cgi->param("pd");
my $error = "";
$error .= "Please enter your username<br/>" if ( !$username );
$error .= "Please specify your password<br/>" if ( !$password );
if ( $error )
{
$ajx->build_html( $cgi, \&form($error, $username, $password));
return 0;
}
else
{
return 1;
}
}
For development, use CGI::Carp qw/fatalsToBrowser/;. This will allow you to see the actual errors your code is producing, rather than "Internal Server Error".
Update: Also, your code is failing because you are misunderstanding how a callback function works. The callback function is not called by you; it is called by the code you pass it to--in this case the module. So you can't provide parameters, the module does. This won't work:
$ajx->build_html( $cgi, \&form($error, $username, $password));
build_html wants to call the function you pass in internally, with its own parameters.
Here you are not allowing to happen. Instead you are calling form() before you call build_html(), then passing in a scalar reference to the result. This fails later, because build_html tries to use that scalar reference as a subroutine reference.
Solution: you just need to use \&form. You will need another way to fill in the fields.
Also:
Form validation is a very common task. Mature Perl modules are available and are widely used for this (for example, HTML::FormFu and Data::Formvalidator). There are also some related modules that appear to add Javascript validation (HTML::FormFu::ExtJS, JavaScript::DataFormValidator). It is probably worth checking these out before you create your own.
Most modern Perl web development is done using a web framework of some sort. The available frameworks are very powerful and worth using for all but the simplest projects. If your goal is to learn, I recommend starting with a framework as early as possible, because development using a framework is quite different from traditional CGI development, and there is a learning curve. I am quite happy with Catalyst, and there are other options as well, such as Mojolicious and Dancer.
I am developing a component in J! 2.5 and want to add a browse button on the backend so the user can pick a file they have previously uploaded. How would I go about this?
This is what I have come up with, if someone can make it more robust and reusable, that would be great. I may do it myself later, but for now I have an impossible deadline.
loadDir.php:
<?php
if(isset($_GET['dir'])) {
//Get array of valid extensions
if(isset($_GET['ext'])) {
if($_GET['ext'] == 'pdf') $validext = array("pdf");
else $validext = array("jpg", "jpeg", "png", "gif");
} else {
$validext = array("pdf", "jpg", "jpeg", "png", "gif");
}
$root = dirname(dirname(dirname(getcwd()))) . "/";
$directory = $root . $_GET['dir'];
$files = scandir($directory);
$thumb_count = 1;
//make sure we haven't gone too high (should never be called)
if(strpos($directory, 'images') == false) $directory = $root . "images";
//TODO: sort array with dirs in front
foreach($files as $file) {
if ($file == '.') continue; //Remove current directory from loop
//If in the images folder, don't let them go higher
if ($file == '..' & $_GET['dir'] == 'images') continue;
$path = $_GET['dir'];
if($file == '..') {
$path = dirname($path);
} else {
$path .= "/".$file;
}
if(is_dir($directory."/".$file)) {
echo "[DIR]".$file."".PHP_EOL;
} else {
//Check to see it's a valid extension
$ext = pathinfo($file, PATHINFO_EXTENSION);
$num = rand(0,100);
if(in_array($ext, $validext)) echo "[FILE]".$file."".PHP_EOL;
}
if(($thumb_count % 5) == 0) echo "<br/>";
$thumb_count++;
}
} else {
echo "Error loading: Directory not available";
}
?>
administrator/components/com_XXX/views/XXX/tmpl/form.php:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
selected_file = "";
function select(id, file) {
$('#' + id).css('background-color', 'red');
selected_file = file;
}
function loadDir(div, path, ext) {
$('#'+div+'Window').load('<?php echo JURI::root();?>administrator/components/com_lot/loadDir.php?div='+div+'&ext='+ext+'&dir='+path);
}
$(document).ready(function() {
$('#floorOpen').on("click", function(){
loadDir('floor', 'images', 'pdf');
$('#floorDialog').show();
});
$('#floorClose').on("click", function(){
$('#floorDialog').hide();
if(selected_file != "") $('#floor_plan').val(selected_file);
selected_file = "";
});
$('#floorCancel').on("click", function(){
$('#floorDialog').hide();
selected_file = "";
});
$('#mainOpen').on("click", function(){
loadDir('main', 'images', 'img');
$('#mainDialog').show();
});
$('#mainClose').on("click", function(){
$('#mainDialog').hide();
if(selected_file != "") $('#main_image').val(selected_file);
selected_file = "";
});
$('#mainCancel').on("click", function(){
$('#mainDialog').hide();
selected_file = "";
});
});
</script>
......
<div id="floorDialog" style="position:absolute;display:none;width:400px;height:300px;border:1px solid #c0c0c0;background-color:#f0f0f0;top:800px;left:400px;">
<div id="floorWindow" style="position:relative;width: 390px;height: 250px;margin: 4px;border: 1px solid #c0c0c0;">
</div>
CancelOK
</div>
<div id="mainDialog" style="position:absolute;display:none;width:400px;height:300px;border:1px solid #c0c0c0;background-color:#f0f0f0;top:800px;left:400px;">
<div id="mainWindow" style="position:relative;width: 390px;height: 250px;margin: 4px;border: 1px solid #c0c0c0;">
</div>
CancelOK
</div>
....
<tr>
<td width="100" align="right" class="key">
<label for="main_image">
<?php echo JText::_( 'Main Image' ); ?>:
</label>
</td>
<td>
<input class="text_area" type="text" name="main_image" id="main_image" size="32" maxlength="250" value="<?php echo $this->lotdata->main_image;?>" />Browse
</td>
</tr>
<tr>
<td width="100" align="right" class="key">
<label for="floor_plan">
<?php echo JText::_( 'Floor Plan' ); ?>:
</label>
</td>
<td>
<input class="text_area" type="text" name="floor_plan" id="floor_plan" size="32" maxlength="250" value="<?php echo $this->lotdata->floor_plan;?>" />Browse
</td>
</tr>
Basically I use AJAX to get a formatted list of files/directories. Then, using javascript we select the file we want and output the path on dialog close.
I think you can use the built in Joomla! form field filelist for this
<field name="myfile" type="filelist" default="" label="Select a file" description="" directory="administrator" filter="" exclude="" stripext="" />
Full options are:
The filelist form field type provides a drop down list of files from a specified directory. If the field has a saved value this is selected when the page is first loaded. If not, the default value (if any) is selected.
Params.filelist.jpg
By default, the first item on the list is '- Do not use -' (which is translatable) and is given the value '-1' and this is followed by '- Use default -' (also translatable) given the value '0'.
type (mandatory) must be filelist.
name (mandatory) is the unique name of the field.
label (mandatory) (translatable) is the
descriptive title of the field. directory (optional) is the
filesystem path to the directory containing the files to be listed.
If omitted the directory given by JPATH_ROOT is assumed.
default (optional) is the default file name.
description (optional)
(translatable) is text that will be shown as a tooltip when the user
moves the mouse over the drop-down box.
filter (optional) is a
regular expression string which is used to filter the list of files
selected for inclusion in the drop-down list. If omitted, all files
in the directory are included. The filter argument expression is
applied before the exclude argument expression. For information on
constructing regular expressions see Regular expressions in parameter
arguments.
exclude (optional) is a regular expression string which is
used to exclude files from the list. The exclude argument expression
is applied after the filter argument expression. For information on
constructing regular expressions see Regular expressions in parameter
arguments.
stripext (optional) is a Boolean argument. If true then
file name extensions will be stripped from the file names listed.
Also note that the file name will be saved without the extension too.
hide_none (optional) is a Boolean argument. If true, the '- Do not
use -' item is omitted from the drop-down list.
hide_default
(optional) is a Boolean argument. If true, the '- Use default -' item
is omitted from the drop-down list.
Here's where I got the list, I'm aware I'm not supposed to just link so I copied/pasted but I'll provide the original link in case the docs get updated.
https://docs.joomla.org/Filelist_form_field_type