Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Item9999: added new formfield "smartbox"
also:

- reworked formfield "icon" to fully access all icons (all famfamfam, all fontawesome)
- implemented a rest interface to query for icons
- fixed "id" formfield
- fixed "topic" formfield
- added support for modern Foswikies
- upgraded "clockpicker" from upstream
  • Loading branch information
MichaelDaum committed Aug 28, 2014
1 parent bd3a0e7 commit 382ee74
Show file tree
Hide file tree
Showing 17 changed files with 564 additions and 145 deletions.
19 changes: 19 additions & 0 deletions .gitignore
@@ -0,0 +1,19 @@
*.gz
*.swp
pub/System/MoreFormfieldsPlugin/git/
pub/System/MoreFormfieldsPlugin/phonenumber.js
pub/System/MoreFormfieldsPlugin/clockpicker.init.js
pub/System/MoreFormfieldsPlugin/clockpicker.css
pub/System/MoreFormfieldsPlugin/clockpicker.js
pub/System/MoreFormfieldsPlugin/userfield.js
pub/System/MoreFormfieldsPlugin/networkaddress.js
pub/System/MoreFormfieldsPlugin/topicfield.js
pub/System/MoreFormfieldsPlugin/iconfield.js
pub/System/MoreFormfieldsPlugin/moreformfields.css
MoreFormfieldsPlugin.md5
MoreFormfieldsPlugin.sha1
MoreFormfieldsPlugin.tgz
MoreFormfieldsPlugin.txt
MoreFormfieldsPlugin.zip
MoreFormfieldsPlugin_installer
MoreFormfieldsPlugin_installer.pl
2 changes: 1 addition & 1 deletion data/System/MoreFormfieldsAjaxHelper.txt
@@ -1,4 +1,4 @@
%META:TOPICINFO{author="micha" comment="reprev" date="1403528623" format="1.1" reprev="7" version="8"}%
%META:TOPICINFO{author="ProjectContributor" comment="reprev" date="1403528623" format="1.1" reprev="7" version="8"}%
%META:TOPICPARENT{name="MoreFormfieldsPlugin"}%
---+!! %TOPIC%

Expand Down
8 changes: 7 additions & 1 deletion data/System/MoreFormfieldsPlugin.txt
@@ -1,7 +1,11 @@
%META:TOPICINFO{author="micha" comment="autosave" date="1403544053" format="1.1" version="3"}%
%META:TOPICINFO{author="ProjectContributor" comment="autosave" date="1403544053" format="1.1" version="3"}%
---+!! %TOPIC%
%SHORTDESCRIPTION%

<div class="foswikiHelp">
Warning: This is a beta release.
</div>

%TOC%

This plugin implements a set of additional special purpose formfields to be used in [[%SYSTEMWEB%.DataForms][DataForm]] definitions.
Expand All @@ -17,6 +21,7 @@ These are:
* =phonenumber=
* =time=
* =icon=
* =smartbox=: the first value of an attribute list (or the one marked with an '*') is used as "any value" place holder

---++ !ExampleForm definition

Expand All @@ -40,6 +45,7 @@ These are:
| Release: | %$RELEASE% |
| Version: | %$VERSION% |
| Change History: | <!-- versions below in reverse order -->&nbsp; |
| 22 Aug 2014: | added smarbox formfield |
| 04 Apr 2014: | fixed compatibility with foswiki >= 1.2.0 |
| 23 Sep 2010: | initial release |
| Dependencies: | %$DEPENDENCIES% |
Expand Down
129 changes: 34 additions & 95 deletions lib/Foswiki/Form/Icon.pm
Expand Up @@ -18,13 +18,10 @@ package Foswiki::Form::Icon;
use strict;
use warnings;

use YAML ();
use Foswiki::Plugins::JQueryPlugin ();
use Foswiki::Form::FieldDefinition ();
our @ISA = ('Foswiki::Form::FieldDefinition');

our %icons = ();

BEGIN {
if ($Foswiki::cfg{UseLocale}) {
require locale;
Expand All @@ -41,15 +38,18 @@ sub new {
$size = 10 if (!$size || $size < 1);
$this->{size} = $size;

if ($this->{type} =~ /\+/) {
my %modifiers = map {lc($_) => 1} grep {!/^icon$/} split(/\+/,$this->{type});
@{$this->{modifiers}} = keys %modifiers;
$this->{groupPattern} = join("|", @{$this->{modifiers}});
}
return $this;
}

$this->{hasMultipleGroups} = (!defined($this->{modifiers}) || scalar(@{$this->{modifiers}}) > 1);
sub param {
my ($this, $key) = @_;

return $this;
unless (defined $this->{_params}) {
my %params = Foswiki::Func::extractParameters($this->{value});
$this->{_params} = \%params;
}

return (defined $key)?$this->{_params}{$key}:$this->{_params};
}

sub renderForEdit {
Expand All @@ -62,96 +62,35 @@ sub renderForEdit {
<script type='text/javascript' src='%PUBURLPATH%/%SYSTEMWEB%/MoreFormfieldsPlugin/iconfield.js'></script>
HERE

$this->readIcons();

my $html = "<select class='".$this->cssClasses("foswikiFontAwesomeIconPicker")."' style='width:".$this->{size}."em' name='".$this->{name}."'>\n";
$html .= '<option></option>';
foreach my $group (sort keys %icons) {
next if $this->{groupPattern} && $group !~ /$this->{groupPattern}/i;

my $groupLabel = $group;
$groupLabel =~ s/^FamFamFam//;
$groupLabel =~ s/([a-z])([A-Z0-9])/$1 $2/g;

$html .= " <optgroup label='$groupLabel'>\n" if scalar$this->{hasMultipleGroups};

foreach my $entry (sort {$a->{id} cmp $b->{id}} @{$icons{$group}}) {
my $text = $entry->{id};
$text =~ s/^fa\-//;
$html .= " <option value='$entry->{id}'".($value && $entry->{id} eq $value?"selected":"")." ".($entry->{url}?"data-url='$entry->{url}'":"").">$text</option>\n";
}

$html .= " </optgroup>\n" if $this->{hasMultipleGroups};
my @htmlData = ();
push @htmlData, "type='hidden'";
push @htmlData, "class='".$this->cssClasses("foswikiIconField")."'";
push @htmlData, "name='$this->{name}'";
push @htmlData, "value='$value'";

my $cat = $this->param("cat");
push @htmlData, "data-cat='$cat'" if $cat;

my $include = $this->param("include");
push @htmlData, "data-include='$include'" if $include;

my $exclude = $this->param("exclude");
push @htmlData, "data-exclude='$exclude'" if $exclude;

my $size = $this->{size};
if (defined $size) {
$size .= "em";
} else {
$size = "element";
}
$html .= "</select>\n";
push @htmlData, 'data-width="'.$size.'"';

return ('', $html);
}
my $field .= "<input ".join(" ", @htmlData)."></input>";

sub readIcons {
my $this = shift;

return if %icons;

# read fontawesome icons
my $iconFile = $Foswiki::cfg{PubDir}.'/'.$Foswiki::cfg{SystemWebName}.'/MoreFormfieldsPlugin/icons.yml';

my $yml = YAML::LoadFile($iconFile);

my $numIcons = 0;
foreach my $entry (@{$yml->{icons}}) {
$entry->{id} = 'fa-'.$entry->{id};
foreach my $cat (@{$entry->{categories}}) {
push @{$icons{$cat}}, $entry;
if ($entry->{aliases}) {
foreach my $alias (@{$entry->{aliases}}) {
my %clone = %$entry;
$clone{id} = 'fa-'.$alias;
$clone{_isAlias} = 1;
push @{$icons{$cat}}, \%clone;
}
}
$numIcons += scalar(@{$icons{$cat}});
}
}

# read icons from icon path
my $iconSearchPath = $Foswiki::cfg{JQueryPlugin}{IconSearchPath}
|| 'FamFamFamSilkIcons, FamFamFamSilkCompanion1Icons, FamFamFamSilkCompanion2Icons, FamFamFamSilkGeoSilkIcons, FamFamFamFlagIcons, FamFamFamMiniIcons, FamFamFamMintIcons';

my @iconSearchPath = split( /\s*,\s*/, $iconSearchPath );

foreach my $item (@iconSearchPath) {
my ( $web, $topic ) = Foswiki::Func::normalizeWebTopicName(
$Foswiki::cfg{SystemWebName}, $item );

my $iconDir =
$Foswiki::cfg{PubDir} . '/'
. $web . '/'
. $topic . '/';

opendir(my $dh, $iconDir) || next;
foreach my $icon (grep { /\.(png|gif|jpe?g)$/i } readdir($dh)) {
next if $icon =~ /^(SilkCompanion1Thumb|index_abc|igp_.*)\.png$/; # filter some more
my $id = $icon;
$id =~ s/\.(png|gif|jpe?g)$//i;
push @{$icons{$topic}}, {
id => $id,
name => $id,
url => Foswiki::Func::getPubUrlPath() . '/' . $web . '/' . $topic . '/' . $icon,
categories => [$topic],
};
}
closedir $dh;

#print STDERR "no icons at $web.$topic\n" unless $icons{$topic};

$numIcons += scalar(@{$icons{$topic}}) if $icons{$topic};
}

#print STDERR "num icons found: $numIcons\n";
return ('', $field);
}


sub renderForDisplay {
my ( $this, $format, $value, $attrs ) = @_;

Expand Down
5 changes: 4 additions & 1 deletion lib/Foswiki/Form/Id.pm
Expand Up @@ -58,8 +58,11 @@ sub beforeSaveHandler {
my $topic = $topicObject->topic;

return unless $topic =~ /(\d+)$/;
my $number = $1;
my $size = $this->{size} || 1;
my $value = sprintf("%0".$size."d", $1);
$size =~ /(\d+)/;
$size = $1;
my $value = sprintf("%0".$size."d", $number);

my $thisField = $topicObject->get('FIELD', $this->{name});
$thisField = {
Expand Down
133 changes: 133 additions & 0 deletions lib/Foswiki/Form/Smartbox.pm
@@ -0,0 +1,133 @@
# See bottom of file for license and copyright information
package Foswiki::Form::Smartbox;

use strict;
use warnings;
use Assert;

use Foswiki::Func();
use Foswiki::Form::Checkbox ();
our @ISA = ('Foswiki::Form::Checkbox');

BEGIN {
if ( $Foswiki::cfg{UseLocale} ) {
require locale;
import locale();
}
}

sub isValueMapped { return 1; }

sub getOptions {
my $this = shift;

my $vals = $this->SUPER::getOptions();
return unless $vals;

$this->{valueMap} = ();

foreach my $val (@$vals) {
if ($val =~ s/\*$//) {
$this->{anyValue} = $val;
$this->{valueMap}{$val} = join(", ", @$vals); # map all values to 'anyValue'
} else {
$this->{valueMap}{$val} = $val;
}
}

$this->{anyValue} = @$vals[0] unless defined $this->{anyValue};

return $vals;
}

sub cssClasses {
my $this = shift;
if ( $this->isMandatory() ) {
push( @_, 'foswikiMandatory' );
}

push @_, 'foswikiSmartboxItem';

return join( ' ', @_ );
}

sub renderForDisplay {
my ($this, $format, $value, $attrs) = @_;


my $displayValue = $this->getDisplayValue($value);
$format =~ s/\$value\(display\)/$displayValue/g;
$format =~ s/\$value/$value/g;

return $this->SUPER::renderForDisplay($format, $value, $attrs);
}

sub getDisplayValue {
my ( $this, $value ) = @_;

return $value unless $this->isValueMapped();

$this->getOptions();
my @vals = ();
foreach my $val ( split( /\s*,\s*/, $value ) ) {
if ( $val eq $this->{anyValue}) {
@vals = $val;
last;
}
if ( defined( $this->{valueMap}{$val} ) ) {
push @vals, $this->{valueMap}{$val};
}
else {
push @vals, $val;
}
}
return join( ", ", @vals );
}

sub renderForEdit {
my ( $this, $topicObject, $value ) = @_;

Foswiki::Func::addToZone("script", "FOSWIKI::SMARTBOX", <<'HERE', "JQUERYPLUGIN");
<script type='text/javascript' src='%PUBURLPATH%/%SYSTEMWEB%/MoreFormfieldsPlugin/smartbox.js'></script>
HERE

my %isSelected = map { $_ => 1 } split( /\s*,\s*/, $value );
my $vals = $this->getOptions();

if ($isSelected{$this->{anyValue}} || scalar(keys %isSelected) == scalar(@$vals) -1) {
$value = join(", ", @$vals);
}

my ($extra, $html) = $this->SUPER::renderForEdit($topicObject, $value);

$html = '<div class="foswikiSmartbox" data-any-value="'.$this->{anyValue}.'">' . $html . '</div>';

return ($extra, $html);
}

1;
__END__
Foswiki - The Free and Open Source Wiki, http://foswiki.org/
Copyright (C) 2008-2014 Foswiki Contributors. Foswiki Contributors
are listed in the AUTHORS file in the root of this distribution.
NOTE: Please extend that file, not this notice.
Additional copyrights apply to some or all of the code in this
file as follows:
Copyright (C) 2005-2007 TWiki Contributors. All Rights Reserved.
TWiki Contributors are listed in the AUTHORS file in the root
of this distribution. NOTE: Please extend that file, not this notice.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. For
more details read LICENSE in the root of this distribution.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
As per the GPL, removal of this notice is prohibited.

0 comments on commit 382ee74

Please sign in to comment.