merged field_group submodule. TODO test new version of field_group, IDs seem to be removed ...
This commit is contained in:
		
							
								
								
									
										40
									
								
								sites/all/modules/contrib/fields/field_group/CHANGELOG.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								sites/all/modules/contrib/fields/field_group/CHANGELOG.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
/* $Id*/
 | 
			
		||||
CHANGELOG for field_group for Drupal 7
 | 
			
		||||
 | 
			
		||||
Field_group 7.x-1.x-dev
 | 
			
		||||
    o Issue #1095316: Field Groups disappear when Content Type is renamed.
 | 
			
		||||
    o Issue #1095316 by swentel: Support for Entity API.
 | 
			
		||||
    o Issue #1095002 by animelion: Upgrading removes all existing field groups.
 | 
			
		||||
    o Issue #1095130 by willvincent: Features export not working with rc2.
 | 
			
		||||
    
 | 
			
		||||
Field_group 7.x-1.0-rc2
 | 
			
		||||
    o Ran through coder, minor.
 | 
			
		||||
    o Issue #1033036 by Stalski, swentel: Create a field_group.api.php.
 | 
			
		||||
    o Made the summary descriptions more human readable.
 | 
			
		||||
    o Issue #1086450: Cannot see red star on some field groups even required fields are set to 1.
 | 
			
		||||
    o #1072292 by shadow_jh, stalski: Using on user settings page but need to hid on registration page.
 | 
			
		||||
    o #1092360 by dww: Move field_group_update_7000 functionality to hook_install().
 | 
			
		||||
    o #1061228 Rewrite the field_group_field_group_is_empty function.
 | 
			
		||||
    o Added ID's to fieldgroups.
 | 
			
		||||
    o Removed unused field_group.admin.inc + menu item. Required asterix moving to field_group setting.
 | 
			
		||||
    o #1045526 by stalski: Make formatter options more user-friendly and logical.
 | 
			
		||||
    o #1041880 by robertgarrigos: duplicated entries in field_group table.
 | 
			
		||||
    o #1043834 by amsri: Field Group module just does not work with profiles 2.
 | 
			
		||||
    
 | 
			
		||||
Field_group 7.x-1.0-rc1
 | 
			
		||||
    o #1006464 Change #groups to #fieldgroups because of name collapsing with form_process_fieldset
 | 
			
		||||
    o #1024184 fix collapsible when mode is set to open
 | 
			
		||||
    o #1020278 by mori: Update fails.
 | 
			
		||||
    o #1020116 by mikegfx: Confusing verbage across group types.
 | 
			
		||||
    o #1018012 by mikegfx: Adding required asterisk to group tabs that have required fields.
 | 
			
		||||
    o #960916 fixed reference warnings.
 | 
			
		||||
    o No label anymore with div>open.
 | 
			
		||||
    o #969258 Added check for fields and extra_fields.
 | 
			
		||||
    o #960916 Fixed notice on for reference on group in field_group_settings.
 | 
			
		||||
    o #961106 Fixed notice on entity type and bundle check.
 | 
			
		||||
    o #962072 by mori: Improve CSS for horizontal tabs & accordion.
 | 
			
		||||
    o Changed Fieldgroup API: defaults and instance_settings are now merged.
 | 
			
		||||
    o Changed save action so everything is gathered during form_state to 
 | 
			
		||||
      postpone saving until the save button is hit.
 | 
			
		||||
    o Changed some important variable name, so it makes more sense and easier to read.
 | 
			
		||||
    o Add basic crud functions.
 | 
			
		||||
							
								
								
									
										339
									
								
								sites/all/modules/contrib/fields/field_group/LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								sites/all/modules/contrib/fields/field_group/LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,339 @@
 | 
			
		||||
                    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 2, June 1991
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
 | 
			
		||||
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
                            Preamble
 | 
			
		||||
 | 
			
		||||
  The licenses for most software are designed to take away your
 | 
			
		||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
			
		||||
License is intended to guarantee your freedom to share and change free
 | 
			
		||||
software--to make sure the software is free for all its users.  This
 | 
			
		||||
General Public License applies to most of the Free Software
 | 
			
		||||
Foundation's software and to any other program whose authors commit to
 | 
			
		||||
using it.  (Some other Free Software Foundation software is covered by
 | 
			
		||||
the GNU Lesser General Public License instead.)  You can apply it to
 | 
			
		||||
your programs, too.
 | 
			
		||||
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
price.  Our General Public Licenses are designed to make sure that you
 | 
			
		||||
have the freedom to distribute copies of free software (and charge for
 | 
			
		||||
this service if you wish), that you receive source code or can get it
 | 
			
		||||
if you want it, that you can change the software or use pieces of it
 | 
			
		||||
in new free programs; and that you know you can do these things.
 | 
			
		||||
 | 
			
		||||
  To protect your rights, we need to make restrictions that forbid
 | 
			
		||||
anyone to deny you these rights or to ask you to surrender the rights.
 | 
			
		||||
These restrictions translate to certain responsibilities for you if you
 | 
			
		||||
distribute copies of the software, or if you modify it.
 | 
			
		||||
 | 
			
		||||
  For example, if you distribute copies of such a program, whether
 | 
			
		||||
gratis or for a fee, you must give the recipients all the rights that
 | 
			
		||||
you have.  You must make sure that they, too, receive or can get the
 | 
			
		||||
source code.  And you must show them these terms so they know their
 | 
			
		||||
rights.
 | 
			
		||||
 | 
			
		||||
  We protect your rights with two steps: (1) copyright the software, and
 | 
			
		||||
(2) offer you this license which gives you legal permission to copy,
 | 
			
		||||
distribute and/or modify the software.
 | 
			
		||||
 | 
			
		||||
  Also, for each author's protection and ours, we want to make certain
 | 
			
		||||
that everyone understands that there is no warranty for this free
 | 
			
		||||
software.  If the software is modified by someone else and passed on, we
 | 
			
		||||
want its recipients to know that what they have is not the original, so
 | 
			
		||||
that any problems introduced by others will not reflect on the original
 | 
			
		||||
authors' reputations.
 | 
			
		||||
 | 
			
		||||
  Finally, any free program is threatened constantly by software
 | 
			
		||||
patents.  We wish to avoid the danger that redistributors of a free
 | 
			
		||||
program will individually obtain patent licenses, in effect making the
 | 
			
		||||
program proprietary.  To prevent this, we have made it clear that any
 | 
			
		||||
patent must be licensed for everyone's free use or not licensed at all.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.
 | 
			
		||||
 | 
			
		||||
                    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
  0. This License applies to any program or other work which contains
 | 
			
		||||
a notice placed by the copyright holder saying it may be distributed
 | 
			
		||||
under the terms of this General Public License.  The "Program", below,
 | 
			
		||||
refers to any such program or work, and a "work based on the Program"
 | 
			
		||||
means either the Program or any derivative work under copyright law:
 | 
			
		||||
that is to say, a work containing the Program or a portion of it,
 | 
			
		||||
either verbatim or with modifications and/or translated into another
 | 
			
		||||
language.  (Hereinafter, translation is included without limitation in
 | 
			
		||||
the term "modification".)  Each licensee is addressed as "you".
 | 
			
		||||
 | 
			
		||||
Activities other than copying, distribution and modification are not
 | 
			
		||||
covered by this License; they are outside its scope.  The act of
 | 
			
		||||
running the Program is not restricted, and the output from the Program
 | 
			
		||||
is covered only if its contents constitute a work based on the
 | 
			
		||||
Program (independent of having been made by running the Program).
 | 
			
		||||
Whether that is true depends on what the Program does.
 | 
			
		||||
 | 
			
		||||
  1. You may copy and distribute verbatim copies of the Program's
 | 
			
		||||
source code as you receive it, in any medium, provided that you
 | 
			
		||||
conspicuously and appropriately publish on each copy an appropriate
 | 
			
		||||
copyright notice and disclaimer of warranty; keep intact all the
 | 
			
		||||
notices that refer to this License and to the absence of any warranty;
 | 
			
		||||
and give any other recipients of the Program a copy of this License
 | 
			
		||||
along with the Program.
 | 
			
		||||
 | 
			
		||||
You may charge a fee for the physical act of transferring a copy, and
 | 
			
		||||
you may at your option offer warranty protection in exchange for a fee.
 | 
			
		||||
 | 
			
		||||
  2. You may modify your copy or copies of the Program or any portion
 | 
			
		||||
of it, thus forming a work based on the Program, and copy and
 | 
			
		||||
distribute such modifications or work under the terms of Section 1
 | 
			
		||||
above, provided that you also meet all of these conditions:
 | 
			
		||||
 | 
			
		||||
    a) You must cause the modified files to carry prominent notices
 | 
			
		||||
    stating that you changed the files and the date of any change.
 | 
			
		||||
 | 
			
		||||
    b) You must cause any work that you distribute or publish, that in
 | 
			
		||||
    whole or in part contains or is derived from the Program or any
 | 
			
		||||
    part thereof, to be licensed as a whole at no charge to all third
 | 
			
		||||
    parties under the terms of this License.
 | 
			
		||||
 | 
			
		||||
    c) If the modified program normally reads commands interactively
 | 
			
		||||
    when run, you must cause it, when started running for such
 | 
			
		||||
    interactive use in the most ordinary way, to print or display an
 | 
			
		||||
    announcement including an appropriate copyright notice and a
 | 
			
		||||
    notice that there is no warranty (or else, saying that you provide
 | 
			
		||||
    a warranty) and that users may redistribute the program under
 | 
			
		||||
    these conditions, and telling the user how to view a copy of this
 | 
			
		||||
    License.  (Exception: if the Program itself is interactive but
 | 
			
		||||
    does not normally print such an announcement, your work based on
 | 
			
		||||
    the Program is not required to print an announcement.)
 | 
			
		||||
 | 
			
		||||
These requirements apply to the modified work as a whole.  If
 | 
			
		||||
identifiable sections of that work are not derived from the Program,
 | 
			
		||||
and can be reasonably considered independent and separate works in
 | 
			
		||||
themselves, then this License, and its terms, do not apply to those
 | 
			
		||||
sections when you distribute them as separate works.  But when you
 | 
			
		||||
distribute the same sections as part of a whole which is a work based
 | 
			
		||||
on the Program, the distribution of the whole must be on the terms of
 | 
			
		||||
this License, whose permissions for other licensees extend to the
 | 
			
		||||
entire whole, and thus to each and every part regardless of who wrote it.
 | 
			
		||||
 | 
			
		||||
Thus, it is not the intent of this section to claim rights or contest
 | 
			
		||||
your rights to work written entirely by you; rather, the intent is to
 | 
			
		||||
exercise the right to control the distribution of derivative or
 | 
			
		||||
collective works based on the Program.
 | 
			
		||||
 | 
			
		||||
In addition, mere aggregation of another work not based on the Program
 | 
			
		||||
with the Program (or with a work based on the Program) on a volume of
 | 
			
		||||
a storage or distribution medium does not bring the other work under
 | 
			
		||||
the scope of this License.
 | 
			
		||||
 | 
			
		||||
  3. You may copy and distribute the Program (or a work based on it,
 | 
			
		||||
under Section 2) in object code or executable form under the terms of
 | 
			
		||||
Sections 1 and 2 above provided that you also do one of the following:
 | 
			
		||||
 | 
			
		||||
    a) Accompany it with the complete corresponding machine-readable
 | 
			
		||||
    source code, which must be distributed under the terms of Sections
 | 
			
		||||
    1 and 2 above on a medium customarily used for software interchange; or,
 | 
			
		||||
 | 
			
		||||
    b) Accompany it with a written offer, valid for at least three
 | 
			
		||||
    years, to give any third party, for a charge no more than your
 | 
			
		||||
    cost of physically performing source distribution, a complete
 | 
			
		||||
    machine-readable copy of the corresponding source code, to be
 | 
			
		||||
    distributed under the terms of Sections 1 and 2 above on a medium
 | 
			
		||||
    customarily used for software interchange; or,
 | 
			
		||||
 | 
			
		||||
    c) Accompany it with the information you received as to the offer
 | 
			
		||||
    to distribute corresponding source code.  (This alternative is
 | 
			
		||||
    allowed only for noncommercial distribution and only if you
 | 
			
		||||
    received the program in object code or executable form with such
 | 
			
		||||
    an offer, in accord with Subsection b above.)
 | 
			
		||||
 | 
			
		||||
The source code for a work means the preferred form of the work for
 | 
			
		||||
making modifications to it.  For an executable work, complete source
 | 
			
		||||
code means all the source code for all modules it contains, plus any
 | 
			
		||||
associated interface definition files, plus the scripts used to
 | 
			
		||||
control compilation and installation of the executable.  However, as a
 | 
			
		||||
special exception, the source code distributed need not include
 | 
			
		||||
anything that is normally distributed (in either source or binary
 | 
			
		||||
form) with the major components (compiler, kernel, and so on) of the
 | 
			
		||||
operating system on which the executable runs, unless that component
 | 
			
		||||
itself accompanies the executable.
 | 
			
		||||
 | 
			
		||||
If distribution of executable or object code is made by offering
 | 
			
		||||
access to copy from a designated place, then offering equivalent
 | 
			
		||||
access to copy the source code from the same place counts as
 | 
			
		||||
distribution of the source code, even though third parties are not
 | 
			
		||||
compelled to copy the source along with the object code.
 | 
			
		||||
 | 
			
		||||
  4. You may not copy, modify, sublicense, or distribute the Program
 | 
			
		||||
except as expressly provided under this License.  Any attempt
 | 
			
		||||
otherwise to copy, modify, sublicense or distribute the Program is
 | 
			
		||||
void, and will automatically terminate your rights under this License.
 | 
			
		||||
However, parties who have received copies, or rights, from you under
 | 
			
		||||
this License will not have their licenses terminated so long as such
 | 
			
		||||
parties remain in full compliance.
 | 
			
		||||
 | 
			
		||||
  5. You are not required to accept this License, since you have not
 | 
			
		||||
signed it.  However, nothing else grants you permission to modify or
 | 
			
		||||
distribute the Program or its derivative works.  These actions are
 | 
			
		||||
prohibited by law if you do not accept this License.  Therefore, by
 | 
			
		||||
modifying or distributing the Program (or any work based on the
 | 
			
		||||
Program), you indicate your acceptance of this License to do so, and
 | 
			
		||||
all its terms and conditions for copying, distributing or modifying
 | 
			
		||||
the Program or works based on it.
 | 
			
		||||
 | 
			
		||||
  6. Each time you redistribute the Program (or any work based on the
 | 
			
		||||
Program), the recipient automatically receives a license from the
 | 
			
		||||
original licensor to copy, distribute or modify the Program subject to
 | 
			
		||||
these terms and conditions.  You may not impose any further
 | 
			
		||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
			
		||||
You are not responsible for enforcing compliance by third parties to
 | 
			
		||||
this License.
 | 
			
		||||
 | 
			
		||||
  7. If, as a consequence of a court judgment or allegation of patent
 | 
			
		||||
infringement or for any other reason (not limited to patent issues),
 | 
			
		||||
conditions are imposed on you (whether by court order, agreement or
 | 
			
		||||
otherwise) that contradict the conditions of this License, they do not
 | 
			
		||||
excuse you from the conditions of this License.  If you cannot
 | 
			
		||||
distribute so as to satisfy simultaneously your obligations under this
 | 
			
		||||
License and any other pertinent obligations, then as a consequence you
 | 
			
		||||
may not distribute the Program at all.  For example, if a patent
 | 
			
		||||
license would not permit royalty-free redistribution of the Program by
 | 
			
		||||
all those who receive copies directly or indirectly through you, then
 | 
			
		||||
the only way you could satisfy both it and this License would be to
 | 
			
		||||
refrain entirely from distribution of the Program.
 | 
			
		||||
 | 
			
		||||
If any portion of this section is held invalid or unenforceable under
 | 
			
		||||
any particular circumstance, the balance of the section is intended to
 | 
			
		||||
apply and the section as a whole is intended to apply in other
 | 
			
		||||
circumstances.
 | 
			
		||||
 | 
			
		||||
It is not the purpose of this section to induce you to infringe any
 | 
			
		||||
patents or other property right claims or to contest validity of any
 | 
			
		||||
such claims; this section has the sole purpose of protecting the
 | 
			
		||||
integrity of the free software distribution system, which is
 | 
			
		||||
implemented by public license practices.  Many people have made
 | 
			
		||||
generous contributions to the wide range of software distributed
 | 
			
		||||
through that system in reliance on consistent application of that
 | 
			
		||||
system; it is up to the author/donor to decide if he or she is willing
 | 
			
		||||
to distribute software through any other system and a licensee cannot
 | 
			
		||||
impose that choice.
 | 
			
		||||
 | 
			
		||||
This section is intended to make thoroughly clear what is believed to
 | 
			
		||||
be a consequence of the rest of this License.
 | 
			
		||||
 | 
			
		||||
  8. If the distribution and/or use of the Program is restricted in
 | 
			
		||||
certain countries either by patents or by copyrighted interfaces, the
 | 
			
		||||
original copyright holder who places the Program under this License
 | 
			
		||||
may add an explicit geographical distribution limitation excluding
 | 
			
		||||
those countries, so that distribution is permitted only in or among
 | 
			
		||||
countries not thus excluded.  In such case, this License incorporates
 | 
			
		||||
the limitation as if written in the body of this License.
 | 
			
		||||
 | 
			
		||||
  9. The Free Software Foundation may publish revised and/or new versions
 | 
			
		||||
of the General Public License from time to time.  Such new versions will
 | 
			
		||||
be similar in spirit to the present version, but may differ in detail to
 | 
			
		||||
address new problems or concerns.
 | 
			
		||||
 | 
			
		||||
Each version is given a distinguishing version number.  If the Program
 | 
			
		||||
specifies a version number of this License which applies to it and "any
 | 
			
		||||
later version", you have the option of following the terms and conditions
 | 
			
		||||
either of that version or of any later version published by the Free
 | 
			
		||||
Software Foundation.  If the Program does not specify a version number of
 | 
			
		||||
this License, you may choose any version ever published by the Free Software
 | 
			
		||||
Foundation.
 | 
			
		||||
 | 
			
		||||
  10. If you wish to incorporate parts of the Program into other free
 | 
			
		||||
programs whose distribution conditions are different, write to the author
 | 
			
		||||
to ask for permission.  For software which is copyrighted by the Free
 | 
			
		||||
Software Foundation, write to the Free Software Foundation; we sometimes
 | 
			
		||||
make exceptions for this.  Our decision will be guided by the two goals
 | 
			
		||||
of preserving the free status of all derivatives of our free software and
 | 
			
		||||
of promoting the sharing and reuse of software generally.
 | 
			
		||||
 | 
			
		||||
                            NO WARRANTY
 | 
			
		||||
 | 
			
		||||
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 | 
			
		||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
 | 
			
		||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
 | 
			
		||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 | 
			
		||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
 | 
			
		||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
 | 
			
		||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
 | 
			
		||||
REPAIR OR CORRECTION.
 | 
			
		||||
 | 
			
		||||
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 | 
			
		||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
 | 
			
		||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
 | 
			
		||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
 | 
			
		||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
 | 
			
		||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
 | 
			
		||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 | 
			
		||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 | 
			
		||||
POSSIBILITY OF SUCH DAMAGES.
 | 
			
		||||
 | 
			
		||||
                     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
            How to Apply These Terms to Your New Programs
 | 
			
		||||
 | 
			
		||||
  If you develop a new program, and you want it to be of the greatest
 | 
			
		||||
possible use to the public, the best way to achieve this is to make it
 | 
			
		||||
free software which everyone can redistribute and change under these terms.
 | 
			
		||||
 | 
			
		||||
  To do so, attach the following notices to the program.  It is safest
 | 
			
		||||
to attach them to the start of each source file to most effectively
 | 
			
		||||
convey the exclusion of warranty; and each file should have at least
 | 
			
		||||
the "copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
 | 
			
		||||
    <one line to give the program's name and a brief idea of what it does.>
 | 
			
		||||
    Copyright (C) <year>  <name of author>
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
    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.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License along
 | 
			
		||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
If the program is interactive, make it output a short notice like this
 | 
			
		||||
when it starts in an interactive mode:
 | 
			
		||||
 | 
			
		||||
    Gnomovision version 69, Copyright (C) year name of author
 | 
			
		||||
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
			
		||||
    This is free software, and you are welcome to redistribute it
 | 
			
		||||
    under certain conditions; type `show c' for details.
 | 
			
		||||
 | 
			
		||||
The hypothetical commands `show w' and `show c' should show the appropriate
 | 
			
		||||
parts of the General Public License.  Of course, the commands you use may
 | 
			
		||||
be called something other than `show w' and `show c'; they could even be
 | 
			
		||||
mouse-clicks or menu items--whatever suits your program.
 | 
			
		||||
 | 
			
		||||
You should also get your employer (if you work as a programmer) or your
 | 
			
		||||
school, if any, to sign a "copyright disclaimer" for the program, if
 | 
			
		||||
necessary.  Here is a sample; alter the names:
 | 
			
		||||
 | 
			
		||||
  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 | 
			
		||||
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
 | 
			
		||||
 | 
			
		||||
  <signature of Ty Coon>, 1 April 1989
 | 
			
		||||
  Ty Coon, President of Vice
 | 
			
		||||
 | 
			
		||||
This General Public License does not permit incorporating your program into
 | 
			
		||||
proprietary programs.  If your program is a subroutine library, you may
 | 
			
		||||
consider it more useful to permit linking proprietary applications with the
 | 
			
		||||
library.  If this is what you want to do, use the GNU Lesser General
 | 
			
		||||
Public License instead of this License.
 | 
			
		||||
							
								
								
									
										47
									
								
								sites/all/modules/contrib/fields/field_group/README.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								sites/all/modules/contrib/fields/field_group/README.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
 | 
			
		||||
History:
 | 
			
		||||
  Field_group was written for Drupal 7. For drupal 6, the module is
 | 
			
		||||
  located in the CCK module (http://drupal.org/project/cck).
 | 
			
		||||
  As drupal core has a fields API drupal > 6, the field_group module
 | 
			
		||||
  is considered a contribution.
 | 
			
		||||
 | 
			
		||||
Description:
 | 
			
		||||
  field_group is a module that will group a set of fields. In Drupal7,
 | 
			
		||||
  with fields, one means all fields that come from fieldable entities.
 | 
			
		||||
  You can add fieldgroups in several types with their own format settings.
 | 
			
		||||
  field_group has API functions to add your own formatter and rendering for
 | 
			
		||||
  it.
 | 
			
		||||
  One of the biggest improvements to previous versions, is that fieldgroups
 | 
			
		||||
  have unlimited nesting, better display control.
 | 
			
		||||
  Note that field_group will only group fields, it can not be used to hide
 | 
			
		||||
  certain fields since this a permission matter.
 | 
			
		||||
 | 
			
		||||
Module project page:
 | 
			
		||||
  http://drupal.org/project/field_group
 | 
			
		||||
 | 
			
		||||
Documentation page:
 | 
			
		||||
  http://drupal.org/node/1017838
 | 
			
		||||
  http://drupal.org/node/1017962
 | 
			
		||||
 | 
			
		||||
Available group types:
 | 
			
		||||
  - Fieldsets
 | 
			
		||||
  - Horizontal tabs
 | 
			
		||||
  - Vertical tabs
 | 
			
		||||
  - Accordions
 | 
			
		||||
  - Divs
 | 
			
		||||
  - Multipage steps: <strong>Note: This is only client side.
 | 
			
		||||
  - HTML5 group type
 | 
			
		||||
  - Html element
 | 
			
		||||
 | 
			
		||||
To submit bug reports and feature suggestions, or to track changes:
 | 
			
		||||
  http://drupal.org/project/issues/field_group
 | 
			
		||||
 | 
			
		||||
-- MAINTAINERS --
 | 
			
		||||
 | 
			
		||||
stalski - http://drupal.org/user/322618
 | 
			
		||||
swentel - http://drupal.org/user/107403
 | 
			
		||||
zuuperman - http://drupal.org/user/361625
 | 
			
		||||
 | 
			
		||||
-- INSPIRATORS --
 | 
			
		||||
 | 
			
		||||
yched - http://drupal.org/user/39567
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Override the accordion default style for view_modes.
 | 
			
		||||
 */
 | 
			
		||||
form .ui-accordion h3, form .ui-accordion h3.ui-state-active {
 | 
			
		||||
  padding-left: 0;
 | 
			
		||||
  padding-right: 2em;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										460
									
								
								sites/all/modules/contrib/fields/field_group/field_group.api.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										460
									
								
								sites/all/modules/contrib/fields/field_group/field_group.api.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,460 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Hooks provided by the Field group module.
 | 
			
		||||
 *
 | 
			
		||||
 * Fieldgroup is a module that will wrap fields and other fieldgroups. Nothing more, nothing less.
 | 
			
		||||
 * For this there are formatters we can create on forms and view modes.
 | 
			
		||||
 *
 | 
			
		||||
 * Some of the elements defined in fieldgroup will be ported to the elements module.
 | 
			
		||||
 *
 | 
			
		||||
 * DEVELOPERS NOTES
 | 
			
		||||
 *
 | 
			
		||||
 * - Fieldgroup uses a ''#fieldgroups' property to know what fieldgroups are to be pre_rendered and
 | 
			
		||||
 *   rendered by the field_group module. This means we need to be sure our groups are in #fieldgroups.
 | 
			
		||||
 *   #fieldgroups is later merged with the normal #groups that can be used by any other module.
 | 
			
		||||
 *   This is done to be sure fieldgroup is not taking fieldsets from profile2, commerce line items,
 | 
			
		||||
 *   commerce user profiles, ... .
 | 
			
		||||
 *   When trying to merge a programmatically created field wrapper (div, markup, fieldset, ...) into
 | 
			
		||||
 *   groups, you might consider adding it in #field_groups as well if you want the element processed
 | 
			
		||||
 *   by fieldgroup.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @addtogroup hooks
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Javascript hooks
 | 
			
		||||
 *
 | 
			
		||||
 * Drupal.FieldGroup.Effects.processHook.execute()
 | 
			
		||||
 * See field_group.js for the examples for all implemented formatters.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_group_formatter_info().
 | 
			
		||||
 *
 | 
			
		||||
 * Define the information on formatters. The formatters are
 | 
			
		||||
 * separated by view mode type. We have "form" for all form elements
 | 
			
		||||
 * and "display" will be the real view modes (full, teaser, sticky, ...)
 | 
			
		||||
 *
 | 
			
		||||
 * structure:
 | 
			
		||||
 * @code
 | 
			
		||||
 * array(
 | 
			
		||||
 *   'form' => array(
 | 
			
		||||
 *     'fieldset' => array(
 | 
			
		||||
 *       // required, String with the name of the formatter type.
 | 
			
		||||
 *       'label' => t('Fieldset'),
 | 
			
		||||
 *       // optional, String description of the formatter type.
 | 
			
		||||
 *       'description' => t('This is field group that ...'),
 | 
			
		||||
 *       // required, Array of available formatter options.
 | 
			
		||||
 *       'format_types' => array('open', 'collapsible', 'collapsed'),
 | 
			
		||||
 *       // required, String with default value of the style.
 | 
			
		||||
        'default_formatter' => 'collapsible',
 | 
			
		||||
 *       // optional, Array with key => default_value pairs.
 | 
			
		||||
 *       'instance_settings' => array('key' => 'value'),
 | 
			
		||||
 *     ),
 | 
			
		||||
 *   ),
 | 
			
		||||
 *   'display' => array(
 | 
			
		||||
 *     'fieldset' => array(
 | 
			
		||||
 *       // required, String with the name of the formatter type.
 | 
			
		||||
 *       'label' => t('Fieldset'),
 | 
			
		||||
 *       // optional, String description of the formatter type.
 | 
			
		||||
 *       'description' => t('This is field group that ...'),
 | 
			
		||||
 *       // required, Array of available formatter options.
 | 
			
		||||
 *       'format_types' => array('open', 'collapsible', 'collapsed'),
 | 
			
		||||
 *       // required, String with default value of the style.
 | 
			
		||||
        'default_formatter' => 'collapsible',
 | 
			
		||||
 *       // optional, Array with key => default_value pairs.
 | 
			
		||||
 *       'instance_settings' => array('key' => 'value'),
 | 
			
		||||
 *     ),
 | 
			
		||||
 *   ),
 | 
			
		||||
 * ),
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * @return $formatters
 | 
			
		||||
 *   A collection of available formatting html controls for form
 | 
			
		||||
 *   and display overview type.
 | 
			
		||||
 *
 | 
			
		||||
 * @see field_group_field_group_formatter_info()
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_formatter_info() {
 | 
			
		||||
  return array(
 | 
			
		||||
    'form' => array(
 | 
			
		||||
      'fieldset' => array(
 | 
			
		||||
        'label' => t('Fieldset'),
 | 
			
		||||
        'description' => t('This fieldgroup renders the inner content in a fieldset with the title as legend.'),
 | 
			
		||||
        'format_types' => array('open', 'collapsible', 'collapsed'),
 | 
			
		||||
        'instance_settings' => array('classes' => ''),
 | 
			
		||||
        'default_formatter' => 'collapsible',
 | 
			
		||||
      ),
 | 
			
		||||
    ),
 | 
			
		||||
    'display' => array(
 | 
			
		||||
      'div' => array(
 | 
			
		||||
        'label' => t('Div'),
 | 
			
		||||
        'description' => t('This fieldgroup renders the inner content in a simple div with the title as legend.'),
 | 
			
		||||
        'format_types' => array('open', 'collapsible', 'collapsed'),
 | 
			
		||||
        'instance_settings' => array('effect' => 'none', 'speed' => 'fast', 'classes' => ''),
 | 
			
		||||
        'default_formatter' => 'collapsible',
 | 
			
		||||
      ),
 | 
			
		||||
    ),
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_group_format_settings().
 | 
			
		||||
 *
 | 
			
		||||
 * Defines configuration widget for the settings on a field group
 | 
			
		||||
 * formatter. Eache formatter can have different elements and storage.
 | 
			
		||||
 *
 | 
			
		||||
 * @params Object $group The group object.
 | 
			
		||||
 * @return Array $form The form element for the format settings.
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_format_settings($group) {
 | 
			
		||||
  // Add a wrapper for extra settings to use by others.
 | 
			
		||||
  $form = array(
 | 
			
		||||
    'instance_settings' => array(
 | 
			
		||||
      '#tree' => TRUE,
 | 
			
		||||
      '#weight' => 2,
 | 
			
		||||
    ),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  $field_group_types = field_group_formatter_info();
 | 
			
		||||
  $mode = $group->mode == 'form' ? 'form' : 'display';
 | 
			
		||||
  $formatter = $field_group_types[$mode][$group->format_type];
 | 
			
		||||
 | 
			
		||||
  // Add the required formatter type selector.
 | 
			
		||||
  if (isset($formatter['format_types'])) {
 | 
			
		||||
    $form['formatter'] = array(
 | 
			
		||||
      '#title' => t('Fieldgroup settings'),
 | 
			
		||||
      '#type' => 'select',
 | 
			
		||||
      '#options' => drupal_map_assoc($formatter['format_types']),
 | 
			
		||||
      '#default_value' => isset($group->format_settings['formatter']) ? $group->format_settings['formatter'] : $formatter['default_formatter'],
 | 
			
		||||
      '#weight' => 1,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  if ($mode == 'form') {
 | 
			
		||||
    $form['instance_settings']['required_fields'] = array(
 | 
			
		||||
      '#type' => 'checkbox',
 | 
			
		||||
      '#title' => t('Mark group for required fields.'),
 | 
			
		||||
      '#default_value' => isset($group->format_settings['instance_settings']['required_fields']) ? $group->format_settings['instance_settings']['required_fields'] : (isset($formatter['instance_settings']['required_fields']) ? $formatter['instance_settings']['required_fields'] : ''),
 | 
			
		||||
      '#weight' => 2,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  $form['instance_settings']['classes'] = array(
 | 
			
		||||
    '#title' => t('Extra CSS classes'),
 | 
			
		||||
    '#type' => 'textfield',
 | 
			
		||||
    '#default_value' => isset($group->format_settings['instance_settings']['classes']) ? $group->format_settings['instance_settings']['classes'] : (isset($formatter['instance_settings']['classes']) ? $formatter['instance_settings']['classes'] : ''),
 | 
			
		||||
    '#weight' => 3,
 | 
			
		||||
    '#element_validate' => array('field_group_validate_css_class'),
 | 
			
		||||
  );
 | 
			
		||||
  $form['instance_settings']['description'] = array(
 | 
			
		||||
    '#title' => t('Description'),
 | 
			
		||||
    '#type' => 'textarea',
 | 
			
		||||
    '#default_value' => isset($group->format_settings['instance_settings']['description']) ? $group->format_settings['instance_settings']['description'] : (isset($formatter['instance_settings']['description']) ? $formatter['instance_settings']['description'] : ''),
 | 
			
		||||
    '#weight' => 0,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  // Add optional instance_settings.
 | 
			
		||||
  switch ($group->format_type) {
 | 
			
		||||
    case 'div':
 | 
			
		||||
      $form['instance_settings']['effect'] = array(
 | 
			
		||||
        '#title' => t('Effect'),
 | 
			
		||||
        '#type' => 'select',
 | 
			
		||||
        '#options' => array('none' => t('None'), 'blind' => t('Blind')),
 | 
			
		||||
        '#default_value' => isset($group->format_settings['instance_settings']['effect']) ? $group->format_settings['instance_settings']['effect'] : $formatter['instance_settings']['effect'],
 | 
			
		||||
        '#weight' => 2,
 | 
			
		||||
      );
 | 
			
		||||
      $form['instance_settings']['speed'] = array(
 | 
			
		||||
        '#title' => t('Speed'),
 | 
			
		||||
        '#type' => 'select',
 | 
			
		||||
        '#options' => array('none' => t('None'), 'slow' => t('Slow'), 'fast' => t('Fast')),
 | 
			
		||||
        '#default_value' => isset($group->format_settings['instance_settings']['speed']) ? $group->format_settings['instance_settings']['speed'] : $formatter['instance_settings']['speed'],
 | 
			
		||||
        '#weight' => 3,
 | 
			
		||||
      );
 | 
			
		||||
      break;
 | 
			
		||||
    case 'fieldset':
 | 
			
		||||
      $form['instance_settings']['classes'] = array(
 | 
			
		||||
        '#title' => t('Extra CSS classes'),
 | 
			
		||||
        '#type' => 'textfield',
 | 
			
		||||
        '#default_value' => isset($group->format_settings['instance_settings']['classes']) ? $group->format_settings['instance_settings']['classes'] : $formatter['instance_settings']['classes'],
 | 
			
		||||
        '#weight' => 3,
 | 
			
		||||
        '#element_validate' => array('field_group_validate_css_class'),
 | 
			
		||||
      );
 | 
			
		||||
      break;
 | 
			
		||||
    case 'tabs':
 | 
			
		||||
    case 'htabs':
 | 
			
		||||
    case 'accordion':
 | 
			
		||||
      unset($form['instance_settings']['description']);
 | 
			
		||||
      if (isset($form['instance_settings']['required_fields'])) {
 | 
			
		||||
        unset($form['instance_settings']['required_fields']);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    case 'tab':
 | 
			
		||||
    case 'htab':
 | 
			
		||||
    case 'accordion-item':
 | 
			
		||||
    default:
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return $form;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_group_pre_render().
 | 
			
		||||
 *
 | 
			
		||||
 * This function gives you the oppertunity to create the given
 | 
			
		||||
 * wrapper element that can contain the fields.
 | 
			
		||||
 * In the example beneath, some variables are prepared and used when building the
 | 
			
		||||
 * actual wrapper element. All elements in drupal fapi can be used.
 | 
			
		||||
 *
 | 
			
		||||
 * Note that at this point, the field group has no notion of the fields in it.
 | 
			
		||||
 *
 | 
			
		||||
 * There is also an alternative way of handling this. The default implementation
 | 
			
		||||
 * within field_group calls "field_group_pre_render_<format_type>".
 | 
			
		||||
 * @see field_group_pre_render_fieldset.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Array $elements by address.
 | 
			
		||||
 * @param Object $group The Field group info.
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_pre_render(& $element, $group, & $form) {
 | 
			
		||||
 | 
			
		||||
  // You can prepare some variables to use in the logic.
 | 
			
		||||
  $view_mode = isset($form['#view_mode']) ? $form['#view_mode'] : 'form';
 | 
			
		||||
  $id = $form['#entity_type'] . '_' . $form['#bundle'] . '_' . $view_mode . '_' . $group->group_name;
 | 
			
		||||
 | 
			
		||||
  // Each formatter type can have whole different set of element properties.
 | 
			
		||||
  switch ($group->format_type) {
 | 
			
		||||
 | 
			
		||||
    // Normal or collapsible div.
 | 
			
		||||
    case 'div':
 | 
			
		||||
      $effect = isset($group->format_settings['instance_settings']['effect']) ? $group->format_settings['instance_settings']['effect'] : 'none';
 | 
			
		||||
      $speed = isset($group->format_settings['instance_settings']['speed']) ? $group->format_settings['instance_settings']['speed'] : 'none';
 | 
			
		||||
      $add = array(
 | 
			
		||||
        '#type' => 'markup',
 | 
			
		||||
        '#weight' => $group->weight,
 | 
			
		||||
        '#id' => $id,
 | 
			
		||||
      );
 | 
			
		||||
      $classes .= " speed-$speed effect-$effect";
 | 
			
		||||
      if ($group->format_settings['formatter'] != 'open') {
 | 
			
		||||
        $add['#prefix'] = '<div class="field-group-format ' . $classes . '">
 | 
			
		||||
          <span class="field-group-format-toggler">' . check_plain(t($group->label)) . '</span>
 | 
			
		||||
          <div class="field-group-format-wrapper" style="display: none;">';
 | 
			
		||||
        $add['#suffix'] = '</div></div>';
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        $add['#prefix'] = '<div class="field-group-format ' . $group->group_name . ' ' . $classes . '">';
 | 
			
		||||
        $add['#suffix'] = '</div>';
 | 
			
		||||
      }
 | 
			
		||||
      if (!empty($description)) {
 | 
			
		||||
        $add['#prefix'] .= '<div class="description">' . $description . '</div>';
 | 
			
		||||
      }
 | 
			
		||||
      $element += $add;
 | 
			
		||||
 | 
			
		||||
      if ($effect == 'blind') {
 | 
			
		||||
        drupal_add_library('system', 'effects.blind');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      break;
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_group_pre_render().
 | 
			
		||||
 *
 | 
			
		||||
 * Function that fungates as last resort to alter the pre_render build.
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_pre_render_alter(&$element, $group, & $form) {
 | 
			
		||||
 | 
			
		||||
  if ($group->format_type == 'htab') {
 | 
			
		||||
    $element['#theme_wrappers'] = array('my_horizontal_tab');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_group_build_pre_render_alter().
 | 
			
		||||
 *
 | 
			
		||||
 * Function that fungates as last resort where you can alter things. It is
 | 
			
		||||
 * expected that when you need this function, you have most likely a very custom
 | 
			
		||||
 * case or it is a fix that can be put in field_group core.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Array $elements by address.
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_build_pre_render_alter(& $element) {
 | 
			
		||||
 | 
			
		||||
  // Prepare variables.
 | 
			
		||||
  $display = isset($element['#view_mode']);
 | 
			
		||||
  $groups = array_keys($element['#groups']);
 | 
			
		||||
 | 
			
		||||
  // Example from field_group itself to unset empty elements.
 | 
			
		||||
  if ($display) {
 | 
			
		||||
    foreach (element_children($element) as $name) {
 | 
			
		||||
      if (in_array($name, $groups)) {
 | 
			
		||||
        if (field_group_field_group_is_empty($element[$name], $groups)) {
 | 
			
		||||
          unset($element[$name]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // You might include additional javascript files and stylesheets.
 | 
			
		||||
  $element['#attached']['js'][] = drupal_get_path('module', 'field_group') . '/field_group.js';
 | 
			
		||||
  $element['#attached']['css'][] = drupal_get_path('module', 'field_group') . '/field_group.css';
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_group_format_summary().
 | 
			
		||||
 *
 | 
			
		||||
 * Place to override or change default summary behavior. In most
 | 
			
		||||
 * cases the implementation of field group itself will be enough.
 | 
			
		||||
 *
 | 
			
		||||
 * TODO It might be better to change this hook with already created summaries,
 | 
			
		||||
 * giving the ability to alter or add it later on.
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_format_summary($group) {
 | 
			
		||||
  $output = '';
 | 
			
		||||
  // Create additional summary or change the default setting.
 | 
			
		||||
  return $output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implement hook_ctools_plugin_api().
 | 
			
		||||
 * This hook is needed to let ctools know about exportables.
 | 
			
		||||
 * If you create field groups by using hook_field_group_info, you
 | 
			
		||||
 * will need to include the ctools api hook as well.
 | 
			
		||||
 */
 | 
			
		||||
function hook_ctools_plugin_api($module, $api) {
 | 
			
		||||
  if ($module == 'field_group' && $api == 'field_group') {
 | 
			
		||||
    return array('version' => 1);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_group_info().
 | 
			
		||||
 * Don't forget to include the ctools hook to notify that
 | 
			
		||||
 * your modules has field group exports.
 | 
			
		||||
 * @see hook_ctools_plugin_api.
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_info() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Alter the field group definitions provided by other modules.
 | 
			
		||||
 *
 | 
			
		||||
 * @param array $groups
 | 
			
		||||
 *   Reference to an array of field group definition objects.
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_info_alter(&$groups) {
 | 
			
		||||
  if (!empty($groups['group_issue_metadata|node|project_issue|form'])) {
 | 
			
		||||
    $groups['group_issue_metadata|node|project_issue|form']->data['children'][] = 'taxonomy_vocabulary_9';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_group_update_field_group().
 | 
			
		||||
 *
 | 
			
		||||
 * This hook is invoked by ctools export API.
 | 
			
		||||
 * Note that this is used by ctools and the group could occasional be
 | 
			
		||||
 * the group ID.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $object $group
 | 
			
		||||
 *   The FieldGroup object.
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_update_field_group($group) {
 | 
			
		||||
  // Delete extra data depending on the group.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_group_delete_field_group().
 | 
			
		||||
 *
 | 
			
		||||
 * This hook is invoked by ctools export API.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $object $group
 | 
			
		||||
 *   The FieldGroup object.
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_delete_field_group($group) {
 | 
			
		||||
  // Delete extra data depending on the group.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_group_create_field_group().
 | 
			
		||||
 *
 | 
			
		||||
 * This hook is invoked by ctools export API.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $object $group
 | 
			
		||||
 *   The FieldGroup object.
 | 
			
		||||
 */
 | 
			
		||||
function hook_field_group_create_field_group($group) {
 | 
			
		||||
  // Create extra data depending on the group.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @} End of "addtogroup hooks".
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @addtogroup utility functions
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the groups for a given entity type, bundle and view mode.
 | 
			
		||||
 *
 | 
			
		||||
 * @param String $entity_type
 | 
			
		||||
 *   The Entity type where field groups are requested.
 | 
			
		||||
 * @param String $bundle
 | 
			
		||||
 *   The entity bundle for the field groups.
 | 
			
		||||
 * @param String $view_mode
 | 
			
		||||
 *   The view mode scope for the field groups.
 | 
			
		||||
 *
 | 
			
		||||
 * @see field_group_read_groups()
 | 
			
		||||
 * @see ctools_export_crud_load()
 | 
			
		||||
 * @see ctools_export_crud_load_all()
 | 
			
		||||
 * @see ctools_export_crud_delete()
 | 
			
		||||
 * @see ctools_export_crud_save()
 | 
			
		||||
 */
 | 
			
		||||
function field_group_info_groups($entity_type = NULL, $bundle = NULL, $view_mode = NULL, $reset = FALSE) {
 | 
			
		||||
  // This function caches the result and delegates to field_group_read_groups.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the groups for the given parameters, uncached.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Array $params
 | 
			
		||||
 *   The Entity type where field groups are requested.
 | 
			
		||||
 * @param $enabled
 | 
			
		||||
 *   Return enabled or disabled groups.*
 | 
			
		||||
 *
 | 
			
		||||
 * @see field_group_info_groups()
 | 
			
		||||
 * @see ctools_export_load_object()
 | 
			
		||||
 */
 | 
			
		||||
function field_group_read_groups($conditions = array(), $enabled = TRUE) {
 | 
			
		||||
  // This function loads the requested groups through ctools export api.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Hides field groups including children in a render array.
 | 
			
		||||
 *
 | 
			
		||||
 * @param array $element
 | 
			
		||||
 *   A render array. Can be a form, node, user, ...
 | 
			
		||||
 * @param array $group_names
 | 
			
		||||
 *   An array of field group names that should be hidden.
 | 
			
		||||
 */
 | 
			
		||||
function field_group_hide_field_groups(&$element, $group_names) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @} End of "addtogroup utility functions".
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										23
									
								
								sites/all/modules/contrib/fields/field_group/field_group.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								sites/all/modules/contrib/fields/field_group/field_group.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
/* $Id: field_group.css,v 1.1.2.12 2010/12/22 22:22:35 stalski Exp $ */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Fix for fieldsets in vertical tabs.
 | 
			
		||||
 * Note that this can only be hardcoded to the Seven theme
 | 
			
		||||
 * where people who override this, are in trouble.
 | 
			
		||||
 * This can be removed in next d7 release.
 | 
			
		||||
 */
 | 
			
		||||
.vertical-tabs fieldset.default-fallback,
 | 
			
		||||
div.field-group-tabs-wrapper div.field-type-image fieldset,
 | 
			
		||||
div.field-group-tabs-wrapper div.field-type-file fieldset,
 | 
			
		||||
div.field-group-tabs-wrapper div.field-type-datetime fieldset {
 | 
			
		||||
   border: 1px solid #CCCCCC;
 | 
			
		||||
   margin: 1em 0;
 | 
			
		||||
   padding: 2.5em 0 0;
 | 
			
		||||
   position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.field-group-tabs-wrapper div.field-type-image legend,
 | 
			
		||||
div.field-group-tabs-wrapper div.field-type-file legend,
 | 
			
		||||
div.field-group-tabs-wrapper div.field-type-datetime legend {
 | 
			
		||||
  display: block;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,70 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_features_export_alter().
 | 
			
		||||
 *
 | 
			
		||||
 * For a given feature, add field groups that contain any fields that
 | 
			
		||||
 * are a part of this feature.  Also, add parent groups of any groups
 | 
			
		||||
 * that are a part of this feature.
 | 
			
		||||
 */
 | 
			
		||||
function field_group_features_export_alter(&$export, $module_name) {
 | 
			
		||||
  // Make sure we have fresh data by loading directly.
 | 
			
		||||
  ctools_include('export');
 | 
			
		||||
  $field_groups = ctools_export_load_object('field_group');
 | 
			
		||||
 | 
			
		||||
  // Support the separate field base -vs- field instance structure that was
 | 
			
		||||
  // added in Features v7.x-2.0-beta2.
 | 
			
		||||
  if (function_exists('field_instance_features_export')) {
 | 
			
		||||
    $export_var = 'field_instance';
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    $export_var = 'field';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Add fieldgroups based on the fields that are present.
 | 
			
		||||
  if (!empty($export['features'][$export_var])) {
 | 
			
		||||
    if (!isset($export['features']['field_group'])) {
 | 
			
		||||
      $export['features']['field_group'] = array();
 | 
			
		||||
    }
 | 
			
		||||
    foreach ($export['features'][$export_var] as $field) {
 | 
			
		||||
      list($entity_type, $bundle, $field_name) = explode('-', $field);
 | 
			
		||||
 | 
			
		||||
      foreach ($field_groups as $group_id => $group) {
 | 
			
		||||
 | 
			
		||||
        if ($group->entity_type == $entity_type && $group->bundle == $bundle && in_array($field_name, $group->data['children']) && !in_array($group->identifier, $export['features']['field_group'])) {
 | 
			
		||||
          if (isset($group->export_module) && $group->export_module != $module_name) {
 | 
			
		||||
            $export['dependencies'][$group->export_module] = $group->export_module;
 | 
			
		||||
          }
 | 
			
		||||
          else {
 | 
			
		||||
            $export['features']['field_group'][$group_id] = $group_id;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Add any parent field groups that haven't been selected.
 | 
			
		||||
  if (!empty($export['features']['field_group'])) {
 | 
			
		||||
    foreach ($export['features']['field_group'] as $id) {
 | 
			
		||||
      $group = isset($field_groups[$id]) ? $field_groups[$id] : FALSE;
 | 
			
		||||
 | 
			
		||||
      if ($group && !empty($group->parent_name)) {
 | 
			
		||||
        $parent_id = $group->parent_name . '|' . $group->entity_type . '|' . $group->bundle . '|' . $group->mode;
 | 
			
		||||
        $parent_group = isset($field_groups[$parent_id]) ? $field_groups[$parent_id] : FALSE;
 | 
			
		||||
 | 
			
		||||
        if ($parent_group && !isset($export['features']['field_group'][$parent_id])) {
 | 
			
		||||
          if (isset($parent_group->export_module) && $parent_group->export_module != $module_name) {
 | 
			
		||||
            $export['dependencies'][$parent_group->export_module] = $parent_group->export_module;
 | 
			
		||||
          }
 | 
			
		||||
          else {
 | 
			
		||||
            $export['features']['field_group'][$parent_id] = $parent_id;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if(empty($export['dependencies']['field_group'])) {
 | 
			
		||||
      $export['dependencies']['field_group'] = 'field_group';
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,14 @@
 | 
			
		||||
 | 
			
		||||
#field-overview tr.field-group .group-label,
 | 
			
		||||
#field-display-overview tr.field-group .group-label {
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#field-overview tr.static-region,
 | 
			
		||||
#field-display-overview tr.static-region {
 | 
			
		||||
	background-color: #ddd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#edit-refresh {
 | 
			
		||||
  display:none;
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,137 @@
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
 | 
			
		||||
Drupal.behaviors.fieldUIFieldsOverview = {
 | 
			
		||||
  attach: function (context, settings) {
 | 
			
		||||
    $('table#field-overview', context).once('field-field-overview', function() {
 | 
			
		||||
      Drupal.fieldUIOverview.attach(this, settings.fieldUIRowsData, Drupal.fieldUIFieldOverview);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
  
 | 
			
		||||
/**
 | 
			
		||||
 * Row handlers for the 'Manage fields' screen.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.fieldUIFieldOverview = Drupal.fieldUIFieldOverview || {};
 | 
			
		||||
 | 
			
		||||
Drupal.fieldUIFieldOverview.group = function(row, data) {
 | 
			
		||||
  this.row = row;
 | 
			
		||||
  this.name = data.name;
 | 
			
		||||
  this.region = data.region;
 | 
			
		||||
  this.tableDrag = data.tableDrag;
 | 
			
		||||
 | 
			
		||||
  // Attach change listener to the 'group format' select.
 | 
			
		||||
  this.$formatSelect = $('select.field-group-type', row);
 | 
			
		||||
  this.$formatSelect.change(Drupal.fieldUIOverview.onChange);
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Drupal.fieldUIFieldOverview.group.prototype = {
 | 
			
		||||
  getRegion: function () {
 | 
			
		||||
    return 'main';
 | 
			
		||||
  },
 | 
			
		||||
  
 | 
			
		||||
  regionChange: function (region, recurse) {
 | 
			
		||||
    return {};
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  regionChangeFields: function (region, element, refreshRows) {
 | 
			
		||||
 | 
			
		||||
    // Create a new tabledrag rowObject, that will compute the group's child
 | 
			
		||||
    // rows for us.
 | 
			
		||||
    var tableDrag = element.tableDrag;
 | 
			
		||||
    rowObject = new tableDrag.row(element.row, 'mouse', true);
 | 
			
		||||
    // Skip the main row, we handled it above.
 | 
			
		||||
    rowObject.group.shift();
 | 
			
		||||
 | 
			
		||||
    // Let child rows handlers deal with the region change - without recursing
 | 
			
		||||
    // on nested group rows, we are handling them all here.
 | 
			
		||||
    $.each(rowObject.group, function() {
 | 
			
		||||
      var childRow = this;
 | 
			
		||||
      var childRowHandler = $(childRow).data('fieldUIRowHandler');
 | 
			
		||||
      $.extend(refreshRows, childRowHandler.regionChange(region, false));
 | 
			
		||||
    });
 | 
			
		||||
  }  
 | 
			
		||||
};
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
/**
 | 
			
		||||
 * Row handlers for the 'Manage display' screen.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.fieldUIDisplayOverview = Drupal.fieldUIDisplayOverview || {};
 | 
			
		||||
 | 
			
		||||
Drupal.fieldUIDisplayOverview.group = function(row, data) {
 | 
			
		||||
  this.row = row;
 | 
			
		||||
  this.name = data.name;
 | 
			
		||||
  this.region = data.region;
 | 
			
		||||
  this.tableDrag = data.tableDrag;
 | 
			
		||||
 | 
			
		||||
  // Attach change listener to the 'group format' select.
 | 
			
		||||
  this.$formatSelect = $('select.field-group-type', row);
 | 
			
		||||
  this.$formatSelect.change(Drupal.fieldUIOverview.onChange);
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Drupal.fieldUIDisplayOverview.group.prototype = {
 | 
			
		||||
  getRegion: function () {
 | 
			
		||||
    return (this.$formatSelect.val() == 'hidden') ? 'hidden' : 'visible';
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  regionChange: function (region, recurse) {
 | 
			
		||||
 | 
			
		||||
    // Default recurse to true.
 | 
			
		||||
    recurse = (recurse == undefined) || recurse;
 | 
			
		||||
 | 
			
		||||
    // When triggered by a row drag, the 'format' select needs to be adjusted to
 | 
			
		||||
    // the new region.
 | 
			
		||||
    var currentValue = this.$formatSelect.val();
 | 
			
		||||
    switch (region) {
 | 
			
		||||
      case 'visible':
 | 
			
		||||
        if (currentValue == 'hidden') {
 | 
			
		||||
          // Restore the group format back to 'fieldset'.
 | 
			
		||||
          var value = 'fieldset';
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
        var value = 'hidden';
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    if (value != undefined) {
 | 
			
		||||
      this.$formatSelect.val(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var refreshRows = {};
 | 
			
		||||
    refreshRows[this.name] = this.$formatSelect.get(0);
 | 
			
		||||
 | 
			
		||||
    if (recurse) {
 | 
			
		||||
      this.regionChangeFields(region, this, refreshRows);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return refreshRows;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  regionChangeFields: function (region, element, refreshRows) {
 | 
			
		||||
 | 
			
		||||
    // Create a new tabledrag rowObject, that will compute the group's child
 | 
			
		||||
    // rows for us.
 | 
			
		||||
    var tableDrag = element.tableDrag;
 | 
			
		||||
    rowObject = new tableDrag.row(element.row, 'mouse', true);
 | 
			
		||||
    // Skip the main row, we handled it above.
 | 
			
		||||
    rowObject.group.shift();
 | 
			
		||||
 | 
			
		||||
    // Let child rows handlers deal with the region change - without recursing
 | 
			
		||||
    // on nested group rows, we are handling them all here.
 | 
			
		||||
    $.each(rowObject.group, function() {
 | 
			
		||||
      var childRow = this;
 | 
			
		||||
      var childRowHandler = $(childRow).data('fieldUIRowHandler');
 | 
			
		||||
      $.extend(refreshRows, childRowHandler.regionChange(region, false));
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
name = Fieldgroup
 | 
			
		||||
description = Fieldgroup
 | 
			
		||||
package = Fields
 | 
			
		||||
dependencies[] = field
 | 
			
		||||
dependencies[] = ctools
 | 
			
		||||
core = 7.x
 | 
			
		||||
files[] = field_group.install
 | 
			
		||||
files[] = field_group.module
 | 
			
		||||
files[] = field_group.field_ui.inc
 | 
			
		||||
files[] = field_group.form.inc
 | 
			
		||||
files[] = field_group.features.inc
 | 
			
		||||
files[] = tests/field_group.ui.test
 | 
			
		||||
files[] = tests/field_group.display.test
 | 
			
		||||
; Information added by drupal.org packaging script on 2013-09-25
 | 
			
		||||
version = "7.x-1.3"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "field_group"
 | 
			
		||||
datestamp = "1380124361"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										327
									
								
								sites/all/modules/contrib/fields/field_group/field_group.install
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								sites/all/modules/contrib/fields/field_group/field_group.install
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,327 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Fieldgroup module install file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_schema().
 | 
			
		||||
 */
 | 
			
		||||
function field_group_schema() {
 | 
			
		||||
  $schema['field_group'] = array(
 | 
			
		||||
    'description' => t('Table that contains field group entries and settings.'),
 | 
			
		||||
 | 
			
		||||
    // CTools export definitions.
 | 
			
		||||
    'export' => array(
 | 
			
		||||
      'key' => 'identifier',
 | 
			
		||||
      'identifier' => 'field_group',
 | 
			
		||||
      'default hook' => 'field_group_info',
 | 
			
		||||
      'save callback' => 'field_group_group_save',
 | 
			
		||||
      'delete callback' => 'field_group_group_export_delete',
 | 
			
		||||
      'can disable' => TRUE,
 | 
			
		||||
      'api' => array(
 | 
			
		||||
        'owner' => 'field_group',
 | 
			
		||||
        'api' => 'field_group',
 | 
			
		||||
        'minimum_version' => 1,
 | 
			
		||||
        'current_version' => 1,
 | 
			
		||||
      ),
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
    'fields' => array(
 | 
			
		||||
      'id' => array(
 | 
			
		||||
        'type' => 'serial',
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'description' => 'The primary identifier for a group',
 | 
			
		||||
        'no export' => TRUE,
 | 
			
		||||
      ),
 | 
			
		||||
      'identifier' => array(
 | 
			
		||||
        'type' => 'varchar',
 | 
			
		||||
        'length' => 255,
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'default' => '',
 | 
			
		||||
        'description' => 'The unique string identifier for a group.',
 | 
			
		||||
      ),
 | 
			
		||||
      'group_name' => array(
 | 
			
		||||
        'type' => 'varchar',
 | 
			
		||||
        'length' => 32,
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'default' => '',
 | 
			
		||||
        'description' => 'The name of this group.',
 | 
			
		||||
      ),
 | 
			
		||||
      'entity_type' => array(
 | 
			
		||||
        'type' => 'varchar',
 | 
			
		||||
        'length' => 32,
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'default' => '',
 | 
			
		||||
      ),
 | 
			
		||||
      'bundle' => array(
 | 
			
		||||
        'type' => 'varchar',
 | 
			
		||||
        'length' => 128,
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'default' => ''
 | 
			
		||||
        ),
 | 
			
		||||
      'mode' => array(
 | 
			
		||||
        'type' => 'varchar',
 | 
			
		||||
        'length' => 128,
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'default' => ''
 | 
			
		||||
      ),
 | 
			
		||||
      // @todo 'parent_name' is redundant with the data in the 'children'
 | 
			
		||||
      // entry, brings a risk of inconsistent data. This should be removed from
 | 
			
		||||
      // the schema and pre-computed it if needed in field_group_get_groups().
 | 
			
		||||
      'parent_name' => array(
 | 
			
		||||
        'type' => 'varchar',
 | 
			
		||||
        'length' => 32,
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'default' => '',
 | 
			
		||||
        'description' => 'The parent name for a group',
 | 
			
		||||
      ),
 | 
			
		||||
      'data' => array(
 | 
			
		||||
        'type' => 'blob',
 | 
			
		||||
        'size' => 'big',
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'serialize' => TRUE,
 | 
			
		||||
        'description' => 'Serialized data containing the group properties that do not warrant a dedicated column.',
 | 
			
		||||
      ),
 | 
			
		||||
    ),
 | 
			
		||||
    'primary key' => array('id'),
 | 
			
		||||
    'indexes' => array(
 | 
			
		||||
      'group_name' => array('group_name'),
 | 
			
		||||
    ),
 | 
			
		||||
    'unique keys' => array(
 | 
			
		||||
      'identifier' => array('identifier'),
 | 
			
		||||
    ),
 | 
			
		||||
  );
 | 
			
		||||
  return $schema;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utility function: fetch all the field_group definitions from the database.
 | 
			
		||||
 */
 | 
			
		||||
function _field_group_install_read_groups() {
 | 
			
		||||
  $groups = array();
 | 
			
		||||
  if (db_table_exists('content_group')) {
 | 
			
		||||
    $query = db_select('content_group', 'cg', array('fetch' => PDO::FETCH_ASSOC))
 | 
			
		||||
      ->fields('cg')
 | 
			
		||||
      // We only want non-multigroups.
 | 
			
		||||
      ->condition('group_type', 'standard');
 | 
			
		||||
    foreach ($query->execute() as $record) {
 | 
			
		||||
      $record['settings'] = unserialize($record['settings']);
 | 
			
		||||
      $groups[$record['group_name'] . '-' . $record['type_name']] = $record;
 | 
			
		||||
    }
 | 
			
		||||
    foreach ($groups as $key => $group) {
 | 
			
		||||
      $query2 = db_select('content_group_fields', 'cgf', array('fetch' => PDO::FETCH_ASSOC))
 | 
			
		||||
        ->fields('cgf')
 | 
			
		||||
        ->condition('group_name', $group['group_name']);
 | 
			
		||||
      foreach ($query2->execute() as $field) {
 | 
			
		||||
        $groups[$field['group_name'] . '-' . $field['type_name']]['children'][] = $field;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return $groups;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements of hook_install().
 | 
			
		||||
 *
 | 
			
		||||
 * Because this is a new module in D7, hook_update_N() doesn't help D6
 | 
			
		||||
 * users who upgrade to run the migration path. So, we try that here as
 | 
			
		||||
 * the module is being installed.
 | 
			
		||||
 */
 | 
			
		||||
function field_group_install() {
 | 
			
		||||
 | 
			
		||||
  $groups = _field_group_install_read_groups();
 | 
			
		||||
  module_load_include('module', 'field_group');
 | 
			
		||||
 | 
			
		||||
  if (!empty($groups)) {
 | 
			
		||||
 | 
			
		||||
    module_load_include('module', 'ctools');
 | 
			
		||||
    ctools_include('export');
 | 
			
		||||
 | 
			
		||||
    foreach ($groups as $group) {
 | 
			
		||||
 | 
			
		||||
      $group = (object) $group;
 | 
			
		||||
 | 
			
		||||
      $new = new stdClass();
 | 
			
		||||
      $new->group_name = $group->group_name;
 | 
			
		||||
      $new->entity_type = 'node';
 | 
			
		||||
      $new->bundle = $group->type_name;
 | 
			
		||||
      $new->label = $group->label;
 | 
			
		||||
      $new->parent_name = '';
 | 
			
		||||
      $new->children = array();
 | 
			
		||||
      foreach ($group->children as $child) {
 | 
			
		||||
        $new->children[] = $child['field_name'];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // The form.
 | 
			
		||||
      $new->id = NULL;
 | 
			
		||||
      $new->weight = $group->weight;
 | 
			
		||||
      $new->mode = 'form';
 | 
			
		||||
      $new->format_type = 'fieldset';
 | 
			
		||||
      $new->format_settings = array(
 | 
			
		||||
        'formatter' => preg_match("/fieldset/", $group->settings['form']['style']) ? 'collapsible' : 'collapsed',
 | 
			
		||||
        'instance_settings' => array(),
 | 
			
		||||
      );
 | 
			
		||||
      $new->identifier = $new->group_name . '|' . $new->entity_type . '|' . $new->bundle . '|' . $new->mode;
 | 
			
		||||
      ctools_export_crud_save('field_group', $new);
 | 
			
		||||
 | 
			
		||||
      // The full node.
 | 
			
		||||
      $new->id = NULL;
 | 
			
		||||
      $new->weight = $group->weight;
 | 
			
		||||
      $new->mode = 'default';
 | 
			
		||||
      $new->format_type = $group->settings['display']['full']['format'];
 | 
			
		||||
      $new->format_settings = array(
 | 
			
		||||
        'formatter' => 'collapsible',
 | 
			
		||||
        'instance_settings' => array(),
 | 
			
		||||
      );
 | 
			
		||||
      $new->identifier = $new->group_name . '|' . $new->entity_type . '|' . $new->bundle . '|' . $new->mode;
 | 
			
		||||
      ctools_export_crud_save('field_group', $new);
 | 
			
		||||
 | 
			
		||||
      // The teaser node.
 | 
			
		||||
      $new->id = NULL;
 | 
			
		||||
      $new->weight = $group->weight;
 | 
			
		||||
      $new->mode = 'teaser';
 | 
			
		||||
      $new->format_type = $group->settings['display']['teaser']['format'];
 | 
			
		||||
      $new->format_settings = array(
 | 
			
		||||
        'formatter' => 'collapsible',
 | 
			
		||||
        'instance_settings' => array(),
 | 
			
		||||
      );
 | 
			
		||||
      $new->identifier = $new->group_name . '|' . $new->entity_type . '|' . $new->bundle . '|' . $new->mode;
 | 
			
		||||
      ctools_export_crud_save('field_group', $new);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set weight to 1.
 | 
			
		||||
  db_update('system')
 | 
			
		||||
    ->fields(array('weight' => 1))
 | 
			
		||||
    ->condition('name', 'field_group')
 | 
			
		||||
    ->execute();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update hook on the field_group table to add an unique identifier.
 | 
			
		||||
 */
 | 
			
		||||
function field_group_update_7001() {
 | 
			
		||||
 | 
			
		||||
  if (!db_field_exists('field_group', 'identifier')) {
 | 
			
		||||
    // Add the new string identifier field for ctools.
 | 
			
		||||
    db_add_field('field_group', 'identifier', array(
 | 
			
		||||
      'type' => 'varchar',
 | 
			
		||||
      'length' => 255,
 | 
			
		||||
      'not null' => TRUE,
 | 
			
		||||
      'default' => '',
 | 
			
		||||
      'description' => 'The unique string identifier for a group.',
 | 
			
		||||
    ));
 | 
			
		||||
    // Force drupal's schema to be rebuilt
 | 
			
		||||
    drupal_get_schema('field_group', TRUE);
 | 
			
		||||
 | 
			
		||||
    module_load_include('module', 'field_group');
 | 
			
		||||
    _field_group_recreate_identifiers();
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  db_update('system')
 | 
			
		||||
    ->fields(array('weight' => 1))
 | 
			
		||||
    ->condition('name', 'field_group')
 | 
			
		||||
    ->execute();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update hook to clear cache for new changes to take effect.
 | 
			
		||||
 */
 | 
			
		||||
function field_group_update_7002() {
 | 
			
		||||
 | 
			
		||||
  module_load_include('module', 'field_group');
 | 
			
		||||
 | 
			
		||||
  // This hook is called to satify people with older version of field_group.
 | 
			
		||||
  // This will recreate all identifiers for the field_groups known in database.
 | 
			
		||||
  // At the moment, we only trigger field_groups that are stored in the database, where
 | 
			
		||||
  // we should maybe get all field_groups as ctools has registered them.
 | 
			
		||||
  // See http://drupal.org/node/1169146.
 | 
			
		||||
  // See http://drupal.org/node/1018550.
 | 
			
		||||
  _field_group_recreate_identifiers();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update hook to recreate identifiers.
 | 
			
		||||
 * @see function field_group_update_7002.
 | 
			
		||||
 */
 | 
			
		||||
function field_group_update_7003() {
 | 
			
		||||
 | 
			
		||||
  module_load_include('module', 'field_group');
 | 
			
		||||
  _field_group_recreate_identifiers();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update hook to make sure identifier is set as unique key.
 | 
			
		||||
 */
 | 
			
		||||
function field_group_update_7004() {
 | 
			
		||||
  db_drop_unique_key('field_group', 'identifier');
 | 
			
		||||
  db_add_unique_key('field_group', 'identifier', array('identifier'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks all existing groups and removes optional HTML classes
 | 
			
		||||
 * while adding them as extra classes.
 | 
			
		||||
 */
 | 
			
		||||
function field_group_update_7005() {
 | 
			
		||||
 | 
			
		||||
  // Migrate the field groups so they have a unique identifier.
 | 
			
		||||
  $result = db_select('field_group', 'fg')
 | 
			
		||||
    ->fields('fg')
 | 
			
		||||
    ->execute();
 | 
			
		||||
  $rows = array();
 | 
			
		||||
  foreach($result as $row) {
 | 
			
		||||
    //$row->identifier = $row->group_name . '|' . $row->entity_type . '|' . $row->bundle . '|' . $row->mode;
 | 
			
		||||
    $row->data = unserialize($row->data);
 | 
			
		||||
    $classes = explode(" ", $row->data['format_settings']['instance_settings']['classes']);
 | 
			
		||||
    $optional_classes = array(str_replace("_", "-", $row->group_name), 'field-group-' . $row->data['format_type']);
 | 
			
		||||
    foreach ($optional_classes as $optional_class) {
 | 
			
		||||
      if (!in_array($optional_class, $classes)) {
 | 
			
		||||
        $classes[] = $optional_class;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    $row->data['format_settings']['instance_settings']['classes'] = implode(" ", $classes);
 | 
			
		||||
    $rows[] = $row;
 | 
			
		||||
  }
 | 
			
		||||
  foreach ($rows as $row) {
 | 
			
		||||
    drupal_write_record('field_group', $row, array('id'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Save all optional HTML classes for fieldgroups located in features.
 | 
			
		||||
 * If you need the optional classes, recreate feature after this update.
 | 
			
		||||
 * If not, you can revert it.
 | 
			
		||||
 */
 | 
			
		||||
function field_group_update_7006() {
 | 
			
		||||
  ctools_include("export");
 | 
			
		||||
  // Migrate the field groups so they have a unique identifier.
 | 
			
		||||
  $field_groups = ctools_export_load_object("field_group");
 | 
			
		||||
  foreach ($field_groups as $row) {
 | 
			
		||||
 | 
			
		||||
    // Only update feature field_groups this time.
 | 
			
		||||
    // Don't touch the fieldgroups in db.
 | 
			
		||||
    if ($row->export_type == EXPORT_IN_CODE) {
 | 
			
		||||
      $classes = explode(" ", $row->data['format_settings']['instance_settings']['classes']);
 | 
			
		||||
      $optional_classes = array(str_replace("_", "-", $row->group_name), 'field-group-' . $row->data['format_type']);
 | 
			
		||||
      foreach ($optional_classes as $optional_class) {
 | 
			
		||||
        if (!in_array($optional_class, $classes)) {
 | 
			
		||||
          $classes[] = $optional_class;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      $row->data['format_settings']['instance_settings']['classes'] = implode(" ", $classes);
 | 
			
		||||
      unset($row->id);
 | 
			
		||||
      drupal_write_record('field_group', $row);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										224
									
								
								sites/all/modules/contrib/fields/field_group/field_group.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								sites/all/modules/contrib/fields/field_group/field_group.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,224 @@
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Drupal FieldGroup object.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.FieldGroup = Drupal.FieldGroup || {};
 | 
			
		||||
Drupal.FieldGroup.Effects = Drupal.FieldGroup.Effects || {};
 | 
			
		||||
Drupal.FieldGroup.groupWithfocus = null;
 | 
			
		||||
 | 
			
		||||
Drupal.FieldGroup.setGroupWithfocus = function(element) {
 | 
			
		||||
  element.css({display: 'block'});
 | 
			
		||||
  Drupal.FieldGroup.groupWithfocus = element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements Drupal.FieldGroup.processHook().
 | 
			
		||||
 */
 | 
			
		||||
Drupal.FieldGroup.Effects.processFieldset = {
 | 
			
		||||
  execute: function (context, settings, type) {
 | 
			
		||||
    if (type == 'form') {
 | 
			
		||||
      // Add required fields mark to any fieldsets containing required fields
 | 
			
		||||
      $('fieldset.fieldset', context).once('fieldgroup-effects', function(i) {
 | 
			
		||||
        if ($(this).is('.required-fields') && $(this).find('.form-required').length > 0) {
 | 
			
		||||
          $('legend span.fieldset-legend', $(this)).eq(0).append(' ').append($('.form-required').eq(0).clone());
 | 
			
		||||
        }
 | 
			
		||||
        if ($('.error', $(this)).length) {
 | 
			
		||||
          $('legend span.fieldset-legend', $(this)).eq(0).addClass('error');
 | 
			
		||||
          Drupal.FieldGroup.setGroupWithfocus($(this));
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements Drupal.FieldGroup.processHook().
 | 
			
		||||
 */
 | 
			
		||||
Drupal.FieldGroup.Effects.processAccordion = {
 | 
			
		||||
  execute: function (context, settings, type) {
 | 
			
		||||
    $('div.field-group-accordion-wrapper', context).once('fieldgroup-effects', function () {
 | 
			
		||||
      var wrapper = $(this);
 | 
			
		||||
 | 
			
		||||
      wrapper.accordion({
 | 
			
		||||
        autoHeight: false,
 | 
			
		||||
        active: '.field-group-accordion-active',
 | 
			
		||||
        collapsible: true,
 | 
			
		||||
        changestart: function(event, ui) {
 | 
			
		||||
          if ($(this).hasClass('effect-none')) {
 | 
			
		||||
            ui.options.animated = false;
 | 
			
		||||
          }
 | 
			
		||||
          else {
 | 
			
		||||
            ui.options.animated = 'slide';
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      if (type == 'form') {
 | 
			
		||||
 | 
			
		||||
        var $firstErrorItem = false;
 | 
			
		||||
 | 
			
		||||
        // Add required fields mark to any element containing required fields
 | 
			
		||||
        wrapper.find('div.field-group-accordion-item').each(function(i) {
 | 
			
		||||
 | 
			
		||||
          if ($(this).is('.required-fields') && $(this).find('.form-required').length > 0) {
 | 
			
		||||
            $('h3.ui-accordion-header a').eq(i).append(' ').append($('.form-required').eq(0).clone());
 | 
			
		||||
          }
 | 
			
		||||
          if ($('.error', $(this)).length) {
 | 
			
		||||
            // Save first error item, for focussing it.
 | 
			
		||||
            if (!$firstErrorItem) {
 | 
			
		||||
              $firstErrorItem = $(this).parent().accordion("activate" , i);
 | 
			
		||||
            }
 | 
			
		||||
            $('h3.ui-accordion-header').eq(i).addClass('error');
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Save first error item, for focussing it.
 | 
			
		||||
        if (!$firstErrorItem) {
 | 
			
		||||
          $('.ui-accordion-content-active', $firstErrorItem).css({height: 'auto', width: 'auto', display: 'block'});
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements Drupal.FieldGroup.processHook().
 | 
			
		||||
 */
 | 
			
		||||
Drupal.FieldGroup.Effects.processHtabs = {
 | 
			
		||||
  execute: function (context, settings, type) {
 | 
			
		||||
    if (type == 'form') {
 | 
			
		||||
      // Add required fields mark to any element containing required fields
 | 
			
		||||
      $('fieldset.horizontal-tabs-pane', context).once('fieldgroup-effects', function(i) {
 | 
			
		||||
        if ($(this).is('.required-fields') && $(this).find('.form-required').length > 0) {
 | 
			
		||||
          $(this).data('horizontalTab').link.find('strong:first').after($('.form-required').eq(0).clone()).after(' ');
 | 
			
		||||
        }
 | 
			
		||||
        if ($('.error', $(this)).length) {
 | 
			
		||||
          $(this).data('horizontalTab').link.parent().addClass('error');
 | 
			
		||||
          Drupal.FieldGroup.setGroupWithfocus($(this));
 | 
			
		||||
          $(this).data('horizontalTab').focus();
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements Drupal.FieldGroup.processHook().
 | 
			
		||||
 */
 | 
			
		||||
Drupal.FieldGroup.Effects.processTabs = {
 | 
			
		||||
  execute: function (context, settings, type) {
 | 
			
		||||
    if (type == 'form') {
 | 
			
		||||
      // Add required fields mark to any fieldsets containing required fields
 | 
			
		||||
      $('fieldset.vertical-tabs-pane', context).once('fieldgroup-effects', function(i) {
 | 
			
		||||
        if ($(this).is('.required-fields') && $(this).find('.form-required').length > 0) {
 | 
			
		||||
          $(this).data('verticalTab').link.find('strong:first').after($('.form-required').eq(0).clone()).after(' ');
 | 
			
		||||
        }
 | 
			
		||||
        if ($('.error', $(this)).length) {
 | 
			
		||||
          $(this).data('verticalTab').link.parent().addClass('error');
 | 
			
		||||
          Drupal.FieldGroup.setGroupWithfocus($(this));
 | 
			
		||||
          $(this).data('verticalTab').focus();
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements Drupal.FieldGroup.processHook().
 | 
			
		||||
 *
 | 
			
		||||
 * TODO clean this up meaning check if this is really
 | 
			
		||||
 *      necessary.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.FieldGroup.Effects.processDiv = {
 | 
			
		||||
  execute: function (context, settings, type) {
 | 
			
		||||
 | 
			
		||||
    $('div.collapsible', context).once('fieldgroup-effects', function() {
 | 
			
		||||
      var $wrapper = $(this);
 | 
			
		||||
 | 
			
		||||
      // Turn the legend into a clickable link, but retain span.field-group-format-toggler
 | 
			
		||||
      // for CSS positioning.
 | 
			
		||||
 | 
			
		||||
      var $toggler = $('span.field-group-format-toggler:first', $wrapper);
 | 
			
		||||
      var $link = $('<a class="field-group-format-title" href="#"></a>');
 | 
			
		||||
      $link.prepend($toggler.contents());
 | 
			
		||||
 | 
			
		||||
      // Add required field markers if needed
 | 
			
		||||
      if ($(this).is('.required-fields') && $(this).find('.form-required').length > 0) {
 | 
			
		||||
        $link.append(' ').append($('.form-required').eq(0).clone());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      $link.appendTo($toggler);
 | 
			
		||||
 | 
			
		||||
      // .wrapInner() does not retain bound events.
 | 
			
		||||
      $link.click(function () {
 | 
			
		||||
        var wrapper = $wrapper.get(0);
 | 
			
		||||
        // Don't animate multiple times.
 | 
			
		||||
        if (!wrapper.animating) {
 | 
			
		||||
          wrapper.animating = true;
 | 
			
		||||
          var speed = $wrapper.hasClass('speed-fast') ? 300 : 1000;
 | 
			
		||||
          if ($wrapper.hasClass('effect-none') && $wrapper.hasClass('speed-none')) {
 | 
			
		||||
            $('> .field-group-format-wrapper', wrapper).toggle();
 | 
			
		||||
          }
 | 
			
		||||
          else if ($wrapper.hasClass('effect-blind')) {
 | 
			
		||||
            $('> .field-group-format-wrapper', wrapper).toggle('blind', {}, speed);
 | 
			
		||||
          }
 | 
			
		||||
          else {
 | 
			
		||||
            $('> .field-group-format-wrapper', wrapper).toggle(speed);
 | 
			
		||||
          }
 | 
			
		||||
          wrapper.animating = false;
 | 
			
		||||
        }
 | 
			
		||||
        $wrapper.toggleClass('collapsed');
 | 
			
		||||
        return false;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Behaviors.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.behaviors.fieldGroup = {
 | 
			
		||||
  attach: function (context, settings) {
 | 
			
		||||
    if (settings.field_group == undefined) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Execute all of them.
 | 
			
		||||
    $.each(Drupal.FieldGroup.Effects, function (func) {
 | 
			
		||||
      // We check for a wrapper function in Drupal.field_group as
 | 
			
		||||
      // alternative for dynamic string function calls.
 | 
			
		||||
      var type = func.toLowerCase().replace("process", "");
 | 
			
		||||
      if (settings.field_group[type] != undefined && $.isFunction(this.execute)) {
 | 
			
		||||
        this.execute(context, settings, settings.field_group[type]);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Fixes css for fieldgroups under vertical tabs.
 | 
			
		||||
    $('.fieldset-wrapper .fieldset > legend').css({display: 'block'});
 | 
			
		||||
    $('.vertical-tabs fieldset.fieldset').addClass('default-fallback');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Add a new ID to each fieldset.
 | 
			
		||||
    $('.group-wrapper fieldset').each(function() {
 | 
			
		||||
      // Tats bad, but we have to keep the actual id to prevent layouts to break.
 | 
			
		||||
      var fieldgorupID = 'field_group-' + $(this).attr('id') + ' ' + $(this).attr('id');
 | 
			
		||||
      $(this).attr('id', fieldgorupID);
 | 
			
		||||
    })
 | 
			
		||||
    // Set the hash in url to remember last userselection.
 | 
			
		||||
    $('.group-wrapper ul li').each(function() {
 | 
			
		||||
      var fieldGroupNavigationListIndex = $(this).index();
 | 
			
		||||
      $(this).children('a').click(function() {
 | 
			
		||||
        var fieldset = $('.group-wrapper fieldset').get(fieldGroupNavigationListIndex);
 | 
			
		||||
        // Grab the first id, holding the wanted hashurl.
 | 
			
		||||
        var hashUrl = $(fieldset).attr('id').replace(/^field_group-/, '').split(' ')[0];
 | 
			
		||||
        window.location.hash = hashUrl;
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
							
								
								
									
										2139
									
								
								sites/all/modules/contrib/fields/field_group/field_group.module
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2139
									
								
								sites/all/modules/contrib/fields/field_group/field_group.module
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
div.horizontal-tabs {
 | 
			
		||||
  margin: 0 0 1em 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list {
 | 
			
		||||
  border-right: 0;
 | 
			
		||||
  border-left: 1px solid #dedede;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Layout of each tab */
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li {
 | 
			
		||||
  border-right: 0;
 | 
			
		||||
  border-left: 1px solid #ccc;
 | 
			
		||||
  float: right;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,101 @@
 | 
			
		||||
div.horizontal-tabs {
 | 
			
		||||
  margin: 0 0 1em 0; /* LTR */
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  border: 1px solid #ccc;
 | 
			
		||||
  position: relative; /* IE6/7 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  border: 0;
 | 
			
		||||
  padding: 0px;
 | 
			
		||||
  position: relative; /* IE6 */
 | 
			
		||||
  list-style: none;
 | 
			
		||||
  list-style-image: none; /* IE6 */
 | 
			
		||||
  background-color: #dedede;
 | 
			
		||||
  border-right: 1px solid #dedede; /* LTR */
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: auto;
 | 
			
		||||
  clear: both;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.horizontal-tabs fieldset.horizontal-tabs-pane {
 | 
			
		||||
  padding: 0 1em;
 | 
			
		||||
  border: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fieldset.horizontal-tabs-pane > legend,
 | 
			
		||||
fieldset.vertical-tabs-pane fieldset.horizontal-tabs-pane > legend {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Layout of each tab */
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li {
 | 
			
		||||
  background: #eee;
 | 
			
		||||
  border-right: 1px solid #ccc; /* LTR */
 | 
			
		||||
  padding: 1px;
 | 
			
		||||
  padding-top: 0;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  min-width: 5em; /* IE7 */
 | 
			
		||||
  float: left; /* LTR */
 | 
			
		||||
}
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li.selected {
 | 
			
		||||
  background-color: #fff;
 | 
			
		||||
  padding: 0 0 1px 0;
 | 
			
		||||
}
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li a {
 | 
			
		||||
  display: block;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  padding: 0.5em 0.6em;
 | 
			
		||||
}
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li a:hover {
 | 
			
		||||
  outline: none;
 | 
			
		||||
  background-color: #ededdd;
 | 
			
		||||
}
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li:hover,
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li:focus {
 | 
			
		||||
  background-color: #ddd;
 | 
			
		||||
}
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list :focus {
 | 
			
		||||
  outline: none;
 | 
			
		||||
}
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li a:focus strong,
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li a:active strong,
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li a:hover strong {
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  outline: none;
 | 
			
		||||
}
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li a,
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list li.selected a {
 | 
			
		||||
  display: block;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  padding: 0.5em 0.6em 0.3em 0.6em;
 | 
			
		||||
  position:relative;
 | 
			
		||||
  top: 0px;
 | 
			
		||||
}
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list .selected strong {
 | 
			
		||||
  color: #000;
 | 
			
		||||
}
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs-list .summary {
 | 
			
		||||
  display: block;
 | 
			
		||||
}
 | 
			
		||||
.horizontal-tabs ul.horizontal-tabs ul.horizontal-tabs-list .summary {
 | 
			
		||||
  line-height: normal;
 | 
			
		||||
  margin-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * tab content
 | 
			
		||||
 */
 | 
			
		||||
div.field-group-htabs-wrapper .field-group-format-wrapper {
 | 
			
		||||
  clear: both;
 | 
			
		||||
  padding: 0 0 0.6em;
 | 
			
		||||
}
 | 
			
		||||
/*hide*/
 | 
			
		||||
.horizontal-tabs .horizontal-tab-hidden {
 | 
			
		||||
  display: block;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: -100000px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,203 @@
 | 
			
		||||
(function ($) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This script transforms a set of fieldsets into a stack of horizontal
 | 
			
		||||
 * tabs. Another tab pane can be selected by clicking on the respective
 | 
			
		||||
 * tab.
 | 
			
		||||
 *
 | 
			
		||||
 * Each tab may have a summary which can be updated by another
 | 
			
		||||
 * script. For that to work, each fieldset has an associated
 | 
			
		||||
 * 'horizontalTabCallback' (with jQuery.data() attached to the fieldset),
 | 
			
		||||
 * which is called every time the user performs an update to a form
 | 
			
		||||
 * element inside the tab pane.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.behaviors.horizontalTabs = {
 | 
			
		||||
  attach: function (context) {
 | 
			
		||||
    $('.horizontal-tabs-panes', context).once('horizontal-tabs', function () {
 | 
			
		||||
      var focusID = $(':hidden.horizontal-tabs-active-tab', this).val();
 | 
			
		||||
      var tab_focus;
 | 
			
		||||
 | 
			
		||||
      // Check if there are some fieldsets that can be converted to horizontal-tabs
 | 
			
		||||
      var $fieldsets = $('> fieldset', this);
 | 
			
		||||
      if ($fieldsets.length == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Create the tab column.
 | 
			
		||||
      var tab_list = $('<ul class="horizontal-tabs-list"></ul>');
 | 
			
		||||
      $(this).wrap('<div class="horizontal-tabs clearfix"></div>').before(tab_list);
 | 
			
		||||
 | 
			
		||||
      // Transform each fieldset into a tab.
 | 
			
		||||
      $fieldsets.each(function (i) {
 | 
			
		||||
        var horizontal_tab = new Drupal.horizontalTab({
 | 
			
		||||
          title: $('> legend', this).text(),
 | 
			
		||||
          fieldset: $(this)
 | 
			
		||||
        });
 | 
			
		||||
        horizontal_tab.item.addClass('horizontal-tab-button-' + i);
 | 
			
		||||
        tab_list.append(horizontal_tab.item);
 | 
			
		||||
        $(this)
 | 
			
		||||
          .removeClass('collapsible collapsed')
 | 
			
		||||
          .addClass('horizontal-tabs-pane')
 | 
			
		||||
          .data('horizontalTab', horizontal_tab);
 | 
			
		||||
        if (this.id == focusID) {
 | 
			
		||||
          tab_focus = $(this);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      $('> li:first', tab_list).addClass('first');
 | 
			
		||||
      $('> li:last', tab_list).addClass('last');
 | 
			
		||||
 | 
			
		||||
      if (!tab_focus) {
 | 
			
		||||
        // If the current URL has a fragment and one of the tabs contains an
 | 
			
		||||
        // element that matches the URL fragment, activate that tab.
 | 
			
		||||
        if (window.location.hash && window.location.hash !== '#' && $(window.location.hash, this).length) {
 | 
			
		||||
          tab_focus = $(window.location.hash, this).closest('.horizontal-tabs-pane');
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          tab_focus = $('> .horizontal-tabs-pane:first', this);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (tab_focus.length) {
 | 
			
		||||
        tab_focus.data('horizontalTab').focus();
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The horizontal tab object represents a single tab within a tab group.
 | 
			
		||||
 *
 | 
			
		||||
 * @param settings
 | 
			
		||||
 *   An object with the following keys:
 | 
			
		||||
 *   - title: The name of the tab.
 | 
			
		||||
 *   - fieldset: The jQuery object of the fieldset that is the tab pane.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.horizontalTab = function (settings) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  $.extend(this, settings, Drupal.theme('horizontalTab', settings));
 | 
			
		||||
 | 
			
		||||
  this.link.click(function () {
 | 
			
		||||
    self.focus();
 | 
			
		||||
    return false;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Keyboard events added:
 | 
			
		||||
  // Pressing the Enter key will open the tab pane.
 | 
			
		||||
  this.link.keydown(function(event) {
 | 
			
		||||
    if (event.keyCode == 13) {
 | 
			
		||||
      self.focus();
 | 
			
		||||
      // Set focus on the first input field of the visible fieldset/tab pane.
 | 
			
		||||
      $("fieldset.horizontal-tabs-pane :input:visible:enabled:first").focus();
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Only bind update summary on forms.
 | 
			
		||||
  if (this.fieldset.drupalGetSummary) {
 | 
			
		||||
    this.fieldset.bind('summaryUpdated', function() {
 | 
			
		||||
      self.updateSummary();
 | 
			
		||||
    }).trigger('summaryUpdated');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Drupal.horizontalTab.prototype = {
 | 
			
		||||
  /**
 | 
			
		||||
   * Displays the tab's content pane.
 | 
			
		||||
   */
 | 
			
		||||
  focus: function () {
 | 
			
		||||
    this.fieldset
 | 
			
		||||
      .removeClass('horizontal-tab-hidden')
 | 
			
		||||
      .siblings('fieldset.horizontal-tabs-pane')
 | 
			
		||||
        .each(function () {
 | 
			
		||||
          var tab = $(this).data('horizontalTab');
 | 
			
		||||
          tab.fieldset.addClass('horizontal-tab-hidden');
 | 
			
		||||
          tab.item.removeClass('selected');
 | 
			
		||||
        })
 | 
			
		||||
        .end()
 | 
			
		||||
      .siblings(':hidden.horizontal-tabs-active-tab')
 | 
			
		||||
        .val(this.fieldset.attr('id'));
 | 
			
		||||
    this.item.addClass('selected');
 | 
			
		||||
    // Mark the active tab for screen readers.
 | 
			
		||||
    $('#active-horizontal-tab').remove();
 | 
			
		||||
    this.link.append('<span id="active-horizontal-tab" class="element-invisible">' + Drupal.t('(active tab)') + '</span>');
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Updates the tab's summary.
 | 
			
		||||
   */
 | 
			
		||||
  updateSummary: function () {
 | 
			
		||||
    this.summary.html(this.fieldset.drupalGetSummary());
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Shows a horizontal tab pane.
 | 
			
		||||
   */
 | 
			
		||||
  tabShow: function () {
 | 
			
		||||
    // Display the tab.
 | 
			
		||||
    this.item.removeClass('horizontal-tab-hidden');
 | 
			
		||||
    // Update .first marker for items. We need recurse from parent to retain the
 | 
			
		||||
    // actual DOM element order as jQuery implements sortOrder, but not as public
 | 
			
		||||
    // method.
 | 
			
		||||
    this.item.parent().children('.horizontal-tab-button').removeClass('first')
 | 
			
		||||
      .filter(':visible:first').addClass('first');
 | 
			
		||||
    // Display the fieldset.
 | 
			
		||||
    this.fieldset.removeClass('horizontal-tab-hidden');
 | 
			
		||||
    // Focus this tab.
 | 
			
		||||
    this.focus();
 | 
			
		||||
    return this;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Hides a horizontal tab pane.
 | 
			
		||||
   */
 | 
			
		||||
  tabHide: function () {
 | 
			
		||||
    // Hide this tab.
 | 
			
		||||
    this.item.addClass('horizontal-tab-hidden');
 | 
			
		||||
    // Update .first marker for items. We need recurse from parent to retain the
 | 
			
		||||
    // actual DOM element order as jQuery implements sortOrder, but not as public
 | 
			
		||||
    // method.
 | 
			
		||||
    this.item.parent().children('.horizontal-tab-button').removeClass('first')
 | 
			
		||||
      .filter(':visible:first').addClass('first');
 | 
			
		||||
    // Hide the fieldset.
 | 
			
		||||
    this.fieldset.addClass('horizontal-tab-hidden');
 | 
			
		||||
    // Focus the first visible tab (if there is one).
 | 
			
		||||
    var $firstTab = this.fieldset.siblings('.horizontal-tabs-pane:not(.horizontal-tab-hidden):first');
 | 
			
		||||
    if ($firstTab.length) {
 | 
			
		||||
      $firstTab.data('horizontalTab').focus();
 | 
			
		||||
    }
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Theme function for a horizontal tab.
 | 
			
		||||
 *
 | 
			
		||||
 * @param settings
 | 
			
		||||
 *   An object with the following keys:
 | 
			
		||||
 *   - title: The name of the tab.
 | 
			
		||||
 * @return
 | 
			
		||||
 *   This function has to return an object with at least these keys:
 | 
			
		||||
 *   - item: The root tab jQuery element
 | 
			
		||||
 *   - link: The anchor tag that acts as the clickable area of the tab
 | 
			
		||||
 *       (jQuery version)
 | 
			
		||||
 *   - summary: The jQuery element that contains the tab summary
 | 
			
		||||
 */
 | 
			
		||||
Drupal.theme.prototype.horizontalTab = function (settings) {
 | 
			
		||||
  var tab = {};
 | 
			
		||||
  var idAttr = settings.fieldset.attr('id');
 | 
			
		||||
 | 
			
		||||
  tab.item = $('<li class="horizontal-tab-button" tabindex="-1"></li>')
 | 
			
		||||
    .append(tab.link = $('<a href="#' + idAttr + '"></a>')
 | 
			
		||||
    .append(tab.title = $('<strong></strong>').text(settings.title))
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
  // No need to add summary on frontend.
 | 
			
		||||
  if (settings.fieldset.drupalGetSummary) {
 | 
			
		||||
    tab.link.append(tab.summary = $('<span class="summary"></span>'))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return tab;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
.multipage-controls-list #edit-actions {
 | 
			
		||||
  float: right !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-button {    
 | 
			
		||||
  float: right !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-counter{
 | 
			
		||||
  float: left !important;
 | 
			
		||||
  margin-right: 0 !important;
 | 
			
		||||
  margin-left: 5px !important;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,128 @@
 | 
			
		||||
.multipage-controls-list #edit-actions {
 | 
			
		||||
  float: left; /* LTR */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-button {    
 | 
			
		||||
  margin-bottom: 1em;
 | 
			
		||||
  margin-top: 0;
 | 
			
		||||
  float: left; /* LTR */
 | 
			
		||||
  line-height: 36px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-button a {    
 | 
			
		||||
  padding-top: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-counter {
 | 
			
		||||
  float: right; /* LTR */
 | 
			
		||||
  margin-right: 5px; /* LTR */
 | 
			
		||||
  height: 0;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  top: 1.8em;
 | 
			
		||||
  line-height: 30px;
 | 
			
		||||
  font: 12px arial,sans-serif;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  color:#666;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.multipage-link-previous {
 | 
			
		||||
  font: 12px arial,sans-serif;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  color:#666;
 | 
			
		||||
  -webkit-transition: color 218ms;
 | 
			
		||||
  -moz-transition: color 218ms;
 | 
			
		||||
  -o-transition: color 218ms;
 | 
			
		||||
  transition: color 218ms;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.multipage-link-previous:hover {
 | 
			
		||||
  text-decoration:none;
 | 
			
		||||
  color: #333;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-controls-list input.form-submit {
 | 
			
		||||
  background:none;
 | 
			
		||||
  border: none;
 | 
			
		||||
  border-radius: 2px;
 | 
			
		||||
  -moz-border-radius: 2px;
 | 
			
		||||
  -webkit-border-radius: 2px;
 | 
			
		||||
  border: 1px solid rgba(0, 0, 0, 0.1);
 | 
			
		||||
  font: 12px arial,sans-serif;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  color: #666;
 | 
			
		||||
  text-shadow: 0 1px 0 white;
 | 
			
		||||
  padding: 7px 12px;
 | 
			
		||||
  background: -webkit-gradient(linear,0% 40%,0% 70%,from(whiteSmoke),to(#F1F1F1));
 | 
			
		||||
  -o-transition: border-top-color 0.218s,border-right-color 0.218s,border-bottom-color 0.218s,border-left-color .218s;
 | 
			
		||||
  -webkit-transition: border-color .218s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-controls-list input.form-submit:hover {
 | 
			
		||||
  color:#333;
 | 
			
		||||
  box-shadow: 0 1px 1px rgba(0,0,0,0.1);
 | 
			
		||||
  -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.1);
 | 
			
		||||
  border-color: #939393;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-controls-list input.form-submit:active {
 | 
			
		||||
  background: -webkit-gradient(linear,0% 40%,0% 70%,from(#F1F1F1),to(whiteSmoke));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-controls-list input#edit-submit {
 | 
			
		||||
  background: #4D90FE; /* for non-css3 browsers */
 | 
			
		||||
  background-image: #4D90FE; /* for non-css3 browsers */
 | 
			
		||||
  background-image: -o-linear-gradient(top,#4d90fe,#4787ed);
 | 
			
		||||
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4D90FE', endColorstr='#4787ED'); /* for IE */
 | 
			
		||||
  background: -webkit-gradient(linear, center top, center bottom, from(#4D90FE), to(#4787ED)); /* for webkit browsers */
 | 
			
		||||
  background: -moz-linear-gradient(center top,  #4D90FE,  #4787ED); /* for firefox 3.6+ */ 
 | 
			
		||||
  color: white;
 | 
			
		||||
  text-shadow: none;
 | 
			
		||||
  text-transform: uppercase;
 | 
			
		||||
  min-width: 79px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-controls-list input#edit-submit:hover {
 | 
			
		||||
  background-image: -moz-linear-gradient(top,#4d90fe,#357ae8);
 | 
			
		||||
  background-image: -o-linear-gradient(top,#4d90fe,#357ae8);
 | 
			
		||||
  background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#357ae8));
 | 
			
		||||
  color: white;
 | 
			
		||||
  text-shadow: none;
 | 
			
		||||
  box-shadow: 0 1px 1px rgba(0,0,0,0.2);
 | 
			
		||||
  -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-controls-list input#edit-submit:active {
 | 
			
		||||
  background: #4D90FE;
 | 
			
		||||
  border-color: #2F5BB7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-controls-list input#edit-delete {
 | 
			
		||||
  background-image: -moz-linear-gradient(top,#dd4b39,#d14836);
 | 
			
		||||
  background-image: -o-linear-gradient(top,#dd4b39,#d14836);
 | 
			
		||||
  background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b39),to(#d14836));
 | 
			
		||||
  text-shadow: 0 1px rgba(0, 0, 0, 0.1);
 | 
			
		||||
  border: 1px solid transparent;
 | 
			
		||||
  color: white;
 | 
			
		||||
  text-shadow: none;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-controls-list input#edit-delete:hover {
 | 
			
		||||
  background-image: -moz-linear-gradient(top,#dd4b39,#c53727);
 | 
			
		||||
  background-image: -o-linear-gradient(top,#dd4b39,#c53727);
 | 
			
		||||
  background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b39),to(#c53727));
 | 
			
		||||
  border: 1px solid #B0281A!important;
 | 
			
		||||
  border-bottom: 1px solid #AF301F!important;
 | 
			
		||||
  box-shadow: 0 1px 1px rgba(0,0,0,0.2);
 | 
			
		||||
  -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.2);
 | 
			
		||||
  color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.multipage-controls-list input#edit-delete:active {
 | 
			
		||||
  background-image: -moz-linear-gradient(top,#dd4b39,#b0281a);
 | 
			
		||||
  background-image: -o-linear-gradient(top,#dd4b39,#b0281a);
 | 
			
		||||
  background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b39),to(#b0281a));
 | 
			
		||||
  border: 1px solid #992A1b!important;
 | 
			
		||||
  box-shadow: 0 1px 2px rgba(0,0,0,0.3);
 | 
			
		||||
  -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.3);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,268 @@
 | 
			
		||||
(function ($) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This script transforms a set of wrappers into a stack of multipage pages. 
 | 
			
		||||
 * Another pane can be entered by clicking next/previous.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
Drupal.behaviors.MultiPage = {
 | 
			
		||||
  attach: function (context) {
 | 
			
		||||
    $('.multipage-panes', context).once('multipage', function () {
 | 
			
		||||
 | 
			
		||||
      var focusID = $(':hidden.multipage-active-control', this).val();
 | 
			
		||||
      var paneWithFocus;
 | 
			
		||||
 | 
			
		||||
      // Check if there are some wrappers that can be converted to multipages.
 | 
			
		||||
      var $panes = $('> div.field-group-multipage', this);
 | 
			
		||||
      var $form = $panes.parents('form');
 | 
			
		||||
      if ($panes.length == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Create the next/previous controls.
 | 
			
		||||
      var $controls;
 | 
			
		||||
 | 
			
		||||
      // Transform each div.multipage-pane into a multipage with controls.
 | 
			
		||||
      $panes.each(function () {
 | 
			
		||||
        
 | 
			
		||||
        $controls = $('<div class="multipage-controls-list clearfix"></div>');
 | 
			
		||||
        $(this).append($controls);
 | 
			
		||||
        
 | 
			
		||||
        // Check if the submit button needs to move to the latest pane.
 | 
			
		||||
        if (Drupal.settings.field_group.multipage_move_submit && $('.form-actions').length) {
 | 
			
		||||
          $('.form-actions', $form).remove().appendTo($($controls, $panes.last()));
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        var multipageControl = new Drupal.multipageControl({
 | 
			
		||||
          title: $('> .multipage-pane-title', this).text(),
 | 
			
		||||
          wrapper: $(this),
 | 
			
		||||
          has_next: $(this).next().length,
 | 
			
		||||
          has_previous: $(this).prev().length
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        $controls.append(multipageControl.item);
 | 
			
		||||
        $(this)
 | 
			
		||||
          .addClass('multipage-pane')
 | 
			
		||||
          .data('multipageControl', multipageControl);
 | 
			
		||||
 | 
			
		||||
        if (this.id == focusID) {
 | 
			
		||||
          paneWithFocus = $(this);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      if (paneWithFocus === undefined) {
 | 
			
		||||
        // If the current URL has a fragment and one of the tabs contains an
 | 
			
		||||
        // element that matches the URL fragment, activate that tab.
 | 
			
		||||
        if (window.location.hash && window.location.hash !== '#' && $(window.location.hash, this).length) {
 | 
			
		||||
          paneWithFocus = $(window.location.hash, this).closest('.multipage-pane');
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          paneWithFocus = $('multipage-open', this).length ? $('multipage-open', this) : $('> .multipage-pane:first', this);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (paneWithFocus !== undefined) {
 | 
			
		||||
        paneWithFocus.data('multipageControl').focus();
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The multipagePane object represents a single div as a page.
 | 
			
		||||
 *
 | 
			
		||||
 * @param settings
 | 
			
		||||
 *   An object with the following keys:
 | 
			
		||||
 *   - title: The name of the tab.
 | 
			
		||||
 *   - wrapper: The jQuery object of the <div> that is the tab pane.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.multipageControl = function (settings) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  var controls = Drupal.theme('multipage', settings);
 | 
			
		||||
  $.extend(self, settings, controls);
 | 
			
		||||
 | 
			
		||||
  this.nextLink.click(function () {
 | 
			
		||||
    self.nextPage();
 | 
			
		||||
    return false;
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  this.previousLink.click(function () {
 | 
			
		||||
    self.previousPage();
 | 
			
		||||
    return false;
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
/*
 | 
			
		||||
  // Keyboard events added:
 | 
			
		||||
  // Pressing the Enter key will open the tab pane.
 | 
			
		||||
  this.nextLink.keydown(function(event) {
 | 
			
		||||
    if (event.keyCode == 13) {
 | 
			
		||||
      self.focus();
 | 
			
		||||
      // Set focus on the first input field of the visible wrapper/tab pane.
 | 
			
		||||
      $("div.multipage-pane :input:visible:enabled:first").focus();
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Pressing the Enter key lets you leave the tab again.
 | 
			
		||||
  this.wrapper.keydown(function(event) {
 | 
			
		||||
    // Enter key should not trigger inside <textarea> to allow for multi-line entries.
 | 
			
		||||
    if (event.keyCode == 13 && event.target.nodeName != "TEXTAREA") {
 | 
			
		||||
      // Set focus on the selected tab button again.
 | 
			
		||||
      $(".multipage-tab-button.selected a").focus();
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
*/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Drupal.multipageControl.prototype = {
 | 
			
		||||
    
 | 
			
		||||
  /**
 | 
			
		||||
   * Displays the tab's content pane.
 | 
			
		||||
   */
 | 
			
		||||
  focus: function () {
 | 
			
		||||
    this.wrapper
 | 
			
		||||
      .show()
 | 
			
		||||
      .siblings('div.multipage-pane')
 | 
			
		||||
        .each(function () {
 | 
			
		||||
          var tab = $(this).data('multipageControl');
 | 
			
		||||
          tab.wrapper.hide();
 | 
			
		||||
        })
 | 
			
		||||
        .end()
 | 
			
		||||
      .siblings(':hidden.multipage-active-control')
 | 
			
		||||
        .val(this.wrapper.attr('id'));
 | 
			
		||||
    // Mark the active control for screen readers.
 | 
			
		||||
    $('#active-multipage-control').remove();
 | 
			
		||||
    this.nextLink.after('<span id="active-multipage-control" class="element-invisible">' + Drupal.t('(active page)') + '</span>');
 | 
			
		||||
  },
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Continues to the next page or step in the form.
 | 
			
		||||
   */
 | 
			
		||||
  nextPage: function () {
 | 
			
		||||
    this.wrapper.next().data('multipageControl').focus();
 | 
			
		||||
    $('html, body').scrollTop(this.wrapper.parents('.field-group-multipage-group-wrapper').offset().top);
 | 
			
		||||
  },
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns to the previous page or step in the form.
 | 
			
		||||
   */
 | 
			
		||||
  previousPage: function () {
 | 
			
		||||
    this.wrapper.prev().data('multipageControl').focus();
 | 
			
		||||
    $('html, body').scrollTop(this.wrapper.parents('.field-group-multipage-group-wrapper').offset().top);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Shows a horizontal tab pane.
 | 
			
		||||
   */
 | 
			
		||||
  tabShow: function () {
 | 
			
		||||
    // Display the tab.
 | 
			
		||||
    this.item.show();
 | 
			
		||||
    // Update .first marker for items. We need recurse from parent to retain the
 | 
			
		||||
    // actual DOM element order as jQuery implements sortOrder, but not as public
 | 
			
		||||
    // method.
 | 
			
		||||
    this.item.parent().children('.multipage-control').removeClass('first')
 | 
			
		||||
      .filter(':visible:first').addClass('first');
 | 
			
		||||
    // Display the wrapper.
 | 
			
		||||
    this.wrapper.removeClass('multipage-control-hidden').show();
 | 
			
		||||
    // Focus this tab.
 | 
			
		||||
    this.focus();
 | 
			
		||||
    return this;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Hides a horizontal tab pane.
 | 
			
		||||
   */
 | 
			
		||||
  tabHide: function () {
 | 
			
		||||
    // Hide this tab.
 | 
			
		||||
    this.item.hide();
 | 
			
		||||
    // Update .first marker for items. We need recurse from parent to retain the
 | 
			
		||||
    // actual DOM element order as jQuery implements sortOrder, but not as public
 | 
			
		||||
    // method.
 | 
			
		||||
    this.item.parent().children('.multipage-control').removeClass('first')
 | 
			
		||||
      .filter(':visible:first').addClass('first');
 | 
			
		||||
    // Hide the wrapper.
 | 
			
		||||
    this.wrapper.addClass('horizontal-tab-hidden').hide();
 | 
			
		||||
    // Focus the first visible tab (if there is one).
 | 
			
		||||
    var $firstTab = this.wrapper.siblings('.multipage-pane:not(.multipage-control-hidden):first');
 | 
			
		||||
    if ($firstTab.length) {
 | 
			
		||||
      $firstTab.data('multipageControl').focus();
 | 
			
		||||
    }
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Theme function for a multipage control.
 | 
			
		||||
 *
 | 
			
		||||
 * @param settings
 | 
			
		||||
 *   An object with the following keys:
 | 
			
		||||
 *   - title: The name of the tab.
 | 
			
		||||
 * @return
 | 
			
		||||
 *   This function has to return an object with at least these keys:
 | 
			
		||||
 *   - item: The root tab jQuery element
 | 
			
		||||
 *   - nextLink: The anchor tag that acts as the clickable area of the control
 | 
			
		||||
 *   - nextTitle: The jQuery element that contains the group title
 | 
			
		||||
 *   - previousLink: The anchor tag that acts as the clickable area of the control
 | 
			
		||||
 *   - previousTitle: The jQuery element that contains the group title
 | 
			
		||||
 */
 | 
			
		||||
Drupal.theme.prototype.multipage = function (settings) {
 | 
			
		||||
 | 
			
		||||
  var controls = {};
 | 
			
		||||
  controls.item = $('<span class="multipage-button"></span>');
 | 
			
		||||
  
 | 
			
		||||
  controls.previousLink = $('<input type="button" class="form-submit multipage-link-previous" value="" />');
 | 
			
		||||
  controls.previousTitle = Drupal.t('Previous page');
 | 
			
		||||
  controls.item.append(controls.previousLink.val(controls.previousTitle));  
 | 
			
		||||
  
 | 
			
		||||
  controls.nextLink = $('<input type="button" class="form-submit multipage-link-next" value="" />');
 | 
			
		||||
  controls.nextTitle = Drupal.t('Next page');
 | 
			
		||||
  controls.item.append(controls.nextLink.val(controls.nextTitle));
 | 
			
		||||
  
 | 
			
		||||
  if (!settings.has_next) {
 | 
			
		||||
    controls.nextLink.hide();
 | 
			
		||||
  }
 | 
			
		||||
  if (!settings.has_previous) {
 | 
			
		||||
    controls.previousLink.hide();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  return controls;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Drupal.FieldGroup = Drupal.FieldGroup || {};
 | 
			
		||||
Drupal.FieldGroup.Effects = Drupal.FieldGroup.Effects || {};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements Drupal.FieldGroup.processHook().
 | 
			
		||||
 */
 | 
			
		||||
Drupal.FieldGroup.Effects.processMultipage = {
 | 
			
		||||
  execute: function (context, settings, type) {
 | 
			
		||||
    if (type == 'form') {
 | 
			
		||||
      
 | 
			
		||||
      var $firstErrorItem = false;
 | 
			
		||||
      
 | 
			
		||||
      // Add required fields mark to any element containing required fields
 | 
			
		||||
      $('div.multipage-pane').each(function(i){
 | 
			
		||||
        if ($('.error', $(this)).length) {
 | 
			
		||||
          
 | 
			
		||||
          // Save first error item, for focussing it.
 | 
			
		||||
          if (!$firstErrorItem) {
 | 
			
		||||
            $firstErrorItem = $(this).data('multipageControl');
 | 
			
		||||
          }          
 | 
			
		||||
          
 | 
			
		||||
          Drupal.FieldGroup.setGroupWithfocus($(this));
 | 
			
		||||
          $(this).data('multipageControl').focus();
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // Focus on first multipage that has an error.
 | 
			
		||||
      if ($firstErrorItem) {
 | 
			
		||||
        $firstErrorItem.focus();
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
@@ -0,0 +1,416 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Test file for fieldgroup display.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Group display tests
 | 
			
		||||
 */
 | 
			
		||||
class GroupDisplayTestCase extends DrupalWebTestCase {
 | 
			
		||||
 | 
			
		||||
  protected $node;
 | 
			
		||||
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Display tests',
 | 
			
		||||
      'description' => 'Test the field group display.',
 | 
			
		||||
      'group' => 'Field group',
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function setUp() {
 | 
			
		||||
 | 
			
		||||
    parent::setUp('field_test', 'field_group', 'field_group_test');
 | 
			
		||||
 | 
			
		||||
    $node = new stdClass();
 | 
			
		||||
    $node->type = 'article';
 | 
			
		||||
    $node->title = $this->randomName();
 | 
			
		||||
    $node->status = 1;
 | 
			
		||||
 | 
			
		||||
    // Create test fields.
 | 
			
		||||
    $test_fields = array('field_test', 'field_test_2', 'field_no_access');
 | 
			
		||||
    foreach ($test_fields as $field_name) {
 | 
			
		||||
 | 
			
		||||
      $field = array(
 | 
			
		||||
        'field_name' => $field_name,
 | 
			
		||||
        'type' => 'test_field',
 | 
			
		||||
        'cardinality' => 1,
 | 
			
		||||
      );
 | 
			
		||||
      $instance = array(
 | 
			
		||||
        'field_name' => $field_name,
 | 
			
		||||
        'entity_type' => 'node',
 | 
			
		||||
        'bundle' => 'article',
 | 
			
		||||
        'label' => $this->randomName(),
 | 
			
		||||
        'display' => array(
 | 
			
		||||
          'default' => array(
 | 
			
		||||
            'type' => 'field_test_default',
 | 
			
		||||
            'settings' => array(
 | 
			
		||||
              'test_formatter_setting' => $this->randomName(),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
          'teaser' => array(
 | 
			
		||||
            'type' => 'field_test_default',
 | 
			
		||||
            'settings' => array(
 | 
			
		||||
              'test_formatter_setting' => $this->randomName(),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
      field_create_field($field);
 | 
			
		||||
      field_create_instance($instance);
 | 
			
		||||
 | 
			
		||||
      $node->{$field_name}[LANGUAGE_NONE][0]['value'] = mt_rand(1, 127);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    node_save($node);
 | 
			
		||||
    $this->node = $node;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a new group.
 | 
			
		||||
   * @param array $data
 | 
			
		||||
   *   Data for the field group.
 | 
			
		||||
   */
 | 
			
		||||
  function createGroup($mode, array $data) {
 | 
			
		||||
 | 
			
		||||
    $group_name = 'group_' . drupal_strtolower($this->randomName(8));
 | 
			
		||||
    $identifier = $group_name . '|node|article|' . $mode;
 | 
			
		||||
 | 
			
		||||
    $field_group = new stdClass;
 | 
			
		||||
    $field_group->disabled = FALSE;
 | 
			
		||||
    $field_group->api_version = 1;
 | 
			
		||||
    $field_group->identifier = $identifier;
 | 
			
		||||
    $field_group->group_name = $group_name;
 | 
			
		||||
    $field_group->entity_type = 'node';
 | 
			
		||||
    $field_group->bundle = 'article';
 | 
			
		||||
    $field_group->mode = $mode;
 | 
			
		||||
    $field_group->parent_name = '';
 | 
			
		||||
    $field_group->children = $data['children'];
 | 
			
		||||
    $field_group->data = $data;
 | 
			
		||||
    drupal_write_record('field_group', $field_group);
 | 
			
		||||
    ctools_export_crud_enable('field_group', $field_group->identifier);
 | 
			
		||||
 | 
			
		||||
    return $field_group;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test if an empty  formatter.
 | 
			
		||||
   */
 | 
			
		||||
  function testFieldAccess() {
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Wrapper',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => 'field_no_access',
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'div',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Link',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'required_fields' => 0,
 | 
			
		||||
          'id' => 'wrapper-id',
 | 
			
		||||
          'classes' => 'test-class',
 | 
			
		||||
          'description' => '',
 | 
			
		||||
          'show_label' => FALSE,
 | 
			
		||||
          'label_element' => 'h3',
 | 
			
		||||
          'effect' => 'blink',
 | 
			
		||||
          'speed' => 'fast',
 | 
			
		||||
        ),
 | 
			
		||||
        'formatter' => 'open',
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $group = $this->createGroup('default', $data);
 | 
			
		||||
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'default', TRUE);
 | 
			
		||||
    $this->drupalGet('node/' . $this->node->nid);
 | 
			
		||||
 | 
			
		||||
    // Test if group is not shown.
 | 
			
		||||
    $this->assertNoFieldByXPath("//div[contains(@id, 'wrapper-id')]", NULL, t('Div that contains fields with no access is not shown.'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test the div formatter.
 | 
			
		||||
   */
 | 
			
		||||
  function testDiv() {
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Wrapper',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => 'field_test',
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'div',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Link',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'required_fields' => 0,
 | 
			
		||||
          'id' => 'wrapper-id',
 | 
			
		||||
          'classes' => 'test-class',
 | 
			
		||||
          'description' => '',
 | 
			
		||||
          'show_label' => FALSE,
 | 
			
		||||
          'label_element' => 'h3',
 | 
			
		||||
          'effect' => 'blink',
 | 
			
		||||
          'speed' => 'fast',
 | 
			
		||||
        ),
 | 
			
		||||
        'formatter' => 'open',
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $group = $this->createGroup('default', $data);
 | 
			
		||||
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'default', TRUE);
 | 
			
		||||
    $this->drupalGet('node/' . $this->node->nid);
 | 
			
		||||
 | 
			
		||||
    // Test group ids and classes.
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@id, 'wrapper-id')]", NULL, t('Wrapper id set on wrapper div'));
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class')]", NULL, t('Test class set on wrapper div') . 'class="' . $group->group_name . ' test-class');
 | 
			
		||||
 | 
			
		||||
    // Test group label.
 | 
			
		||||
    $this->assertNoRaw('<h3><span>' . $data['label'] . '</span></h3>', t('Label is not shown'));
 | 
			
		||||
 | 
			
		||||
    // Set show label to true.
 | 
			
		||||
    $group->data['format_settings']['instance_settings']['show_label'] = TRUE;
 | 
			
		||||
 | 
			
		||||
    drupal_write_record('field_group', $group, array('identifier'));
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'default', TRUE);
 | 
			
		||||
    $this->drupalGet('node/' . $this->node->nid);
 | 
			
		||||
    $this->assertRaw('<h3><span>' . $data['label'] . '</span></h3>', t('Label is shown'));
 | 
			
		||||
 | 
			
		||||
    // Change to collapsible
 | 
			
		||||
    $group->data['format_settings']['formatter'] = 'collapsible';
 | 
			
		||||
    drupal_write_record('field_group', $group, array('identifier'));
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'default', TRUE);
 | 
			
		||||
    $this->drupalGet('node/' . $this->node->nid);
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'speed-fast')]", NULL, t('Speed class is set'));
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'effect-blink')]", NULL, t('Effect class is set'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test the horizontal tabs formatter.
 | 
			
		||||
   */
 | 
			
		||||
  function testHorizontalTabs() {
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Tab 1',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => 'field_test',
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'htab',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Tab 1',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'classes' => 'test-class',
 | 
			
		||||
          'description' => '',
 | 
			
		||||
        ),
 | 
			
		||||
        'formatter' => 'open',
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $first_tab = $this->createGroup('default', $data);
 | 
			
		||||
    $first_tab_id = 'node_article_full_' . $first_tab->group_name;
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Tab 2',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => 'field_test_2',
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'htab',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Tab 1',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'classes' => 'test-class-2',
 | 
			
		||||
          'description' => 'description of second tab',
 | 
			
		||||
        ),
 | 
			
		||||
        'formatter' => 'closed',
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $second_tab = $this->createGroup('default', $data);
 | 
			
		||||
    $second_tab_id = 'node_article_full_' . $first_tab->group_name;
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Tabs',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => $first_tab->group_name,
 | 
			
		||||
        1 => $second_tab->group_name,
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'htabs',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Tab 1',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'classes' => 'test-class-wrapper',
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $tabs = $this->createGroup('default', $data);
 | 
			
		||||
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'default', TRUE);
 | 
			
		||||
 | 
			
		||||
    $this->drupalGet('node/' . $this->node->nid);
 | 
			
		||||
 | 
			
		||||
    // Test properties.
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class-wrapper')]", NULL, t('Test class set on tabs wrapper'));
 | 
			
		||||
    $this->assertFieldByXPath("//fieldset[contains(@class, 'test-class-2')]", NULL, t('Test class set on second tab'));
 | 
			
		||||
    $this->assertRaw('<div class="fieldset-description">description of second tab</div>', t('Description of tab is shown'));
 | 
			
		||||
    $this->assertRaw('class="collapsible collapsed test-class-2', t('Second tab is default collapsed'));
 | 
			
		||||
 | 
			
		||||
    // Test if correctly nested
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class-wrapper')]//fieldset[contains(@id, '$first_tab_id')]", NULL, 'First tab is displayed as child of the wrapper.');
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class-wrapper')]//fieldset[contains(@id, '$second_tab_id')]", NULL, 'Second tab is displayed as child of the wrapper.');
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test the vertical tabs formatter.
 | 
			
		||||
   */
 | 
			
		||||
  function testVerticalTabs() {
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Tab 1',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => 'field_test',
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'tab',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Tab 1',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'classes' => 'test-class',
 | 
			
		||||
          'description' => '',
 | 
			
		||||
        ),
 | 
			
		||||
        'formatter' => 'open',
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $first_tab = $this->createGroup('default', $data);
 | 
			
		||||
    $first_tab_id = 'node_article_full_' . $first_tab->group_name;
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Tab 2',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => 'field_test_2',
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'tab',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Tab 1',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'classes' => 'test-class-2',
 | 
			
		||||
          'description' => 'description of second tab',
 | 
			
		||||
        ),
 | 
			
		||||
        'formatter' => 'closed',
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $second_tab = $this->createGroup('default', $data);
 | 
			
		||||
    $second_tab_id = 'node_article_full_' . $first_tab->group_name;
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Tabs',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => $first_tab->group_name,
 | 
			
		||||
        1 => $second_tab->group_name,
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'tabs',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Tab 1',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'classes' => 'test-class-wrapper',
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $tabs = $this->createGroup('default', $data);
 | 
			
		||||
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'default', TRUE);
 | 
			
		||||
 | 
			
		||||
    $this->drupalGet('node/' . $this->node->nid);
 | 
			
		||||
 | 
			
		||||
    // Test properties.
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class-wrapper')]", NULL, t('Test class set on tabs wrapper'));
 | 
			
		||||
    $this->assertFieldByXPath("//fieldset[contains(@class, 'test-class-2')]", NULL, t('Test class set on second tab'));
 | 
			
		||||
    $this->assertRaw('<div class="fieldset-description">description of second tab</div>', t('Description of tab is shown'));
 | 
			
		||||
    $this->assertRaw('class="collapsible collapsed test-class-2', t('Second tab is default collapsed'));
 | 
			
		||||
 | 
			
		||||
    // Test if correctly nested
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class-wrapper')]//fieldset[contains(@id, '$first_tab_id')]", NULL, 'First tab is displayed as child of the wrapper.');
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class-wrapper')]//fieldset[contains(@id, '$second_tab_id')]", NULL, 'Second tab is displayed as child of the wrapper.');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test the accordion formatter.
 | 
			
		||||
   */
 | 
			
		||||
  function testAccordion() {
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Accordion item 1',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => 'field_test',
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'accordion-item',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Accordion item 1',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'classes' => 'test-class',
 | 
			
		||||
        ),
 | 
			
		||||
        'formatter' => 'closed',
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $first_item = $this->createGroup('default', $data);
 | 
			
		||||
    $first_item_id = 'node_article_full_' . $first_item->group_name;
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Accordion item 2',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => 'field_test_2',
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'accordion-item',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Tab 2',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'classes' => 'test-class-2',
 | 
			
		||||
        ),
 | 
			
		||||
        'formatter' => 'open',
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $second_item = $this->createGroup('default', $data);
 | 
			
		||||
    $second_item_id = 'node_article_full_' . $second_item->group_name;
 | 
			
		||||
 | 
			
		||||
    $data = array(
 | 
			
		||||
      'label' => 'Accordion',
 | 
			
		||||
      'weight' => '1',
 | 
			
		||||
      'children' => array(
 | 
			
		||||
        0 => $first_item->group_name,
 | 
			
		||||
        1 => $second_item->group_name,
 | 
			
		||||
      ),
 | 
			
		||||
      'format_type' => 'accordion',
 | 
			
		||||
      'format_settings' => array(
 | 
			
		||||
        'label' => 'Tab 1',
 | 
			
		||||
        'instance_settings' => array(
 | 
			
		||||
          'classes' => 'test-class-wrapper',
 | 
			
		||||
          'effect' => 'bounceslide'
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $accordion = $this->createGroup('default', $data);
 | 
			
		||||
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'default', TRUE);
 | 
			
		||||
 | 
			
		||||
    $this->drupalGet('node/' . $this->node->nid);
 | 
			
		||||
 | 
			
		||||
    // Test properties.
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class-wrapper')]", NULL, t('Test class set on tabs wrapper'));
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'effect-bounceslide')]", NULL, t('Correct effect is set on the accordion'));
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class')]", NULL, t('Accordion item with test-class is shown'));
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class-2')]", NULL, t('Accordion item with test-class-2 is shown'));
 | 
			
		||||
    $this->assertFieldByXPath("//h3[contains(@class, 'field-group-accordion-active')]", NULL, t('Accordion item 2 was set active'));
 | 
			
		||||
 | 
			
		||||
    // Test if correctly nested
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class-wrapper')]//div[contains(@class, 'test-class')]", NULL, 'First item is displayed as child of the wrapper.');
 | 
			
		||||
    $this->assertFieldByXPath("//div[contains(@class, 'test-class-wrapper')]//div[contains(@class, 'test-class-2')]", NULL, 'Second item is displayed as child of the wrapper.');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,109 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Test file for fieldgroup UI.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Group UI tests.
 | 
			
		||||
 */
 | 
			
		||||
class GroupUITestCase extends DrupalWebTestCase {
 | 
			
		||||
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'UI tests',
 | 
			
		||||
      'description' => 'Test the field group UI.',
 | 
			
		||||
      'group' => 'Field group',
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function setUp() {
 | 
			
		||||
    parent::setUp('field_test', 'field_group', 'field_group_test');
 | 
			
		||||
 | 
			
		||||
    // Create test user.
 | 
			
		||||
    $admin_user = $this->drupalCreateUser(array('administer content types', 'administer nodes', 'access administration pages', 'bypass node access'));
 | 
			
		||||
    $this->drupalLogin($admin_user);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test the creation a group on the article content type.
 | 
			
		||||
   */
 | 
			
		||||
  function createGroup() {
 | 
			
		||||
 | 
			
		||||
    // Create random group name.
 | 
			
		||||
    $this->group_label = $this->randomName(8);
 | 
			
		||||
    $this->group_name_input = drupal_strtolower($this->randomName(8));
 | 
			
		||||
    $this->group_name = 'group_' . $this->group_name_input;
 | 
			
		||||
 | 
			
		||||
    // Setup new group.
 | 
			
		||||
    $group = array(
 | 
			
		||||
      'fields[_add_new_group][label]' => $this->group_label,
 | 
			
		||||
      'fields[_add_new_group][group_name]' => $this->group_name_input,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Add new group on the 'Manage fields' page.
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/article/fields', $group, t('Save'));
 | 
			
		||||
 | 
			
		||||
    $this->assertRaw(t('New group %label successfully created.', array('%label' => $this->group_label)), t('Group message displayed on screen.'));
 | 
			
		||||
 | 
			
		||||
    // Test if group is in the $groups array.
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'form', TRUE);
 | 
			
		||||
    $this->assertTrue(array_key_exists($this->group_name, $groups), t('Group found in groups array'));
 | 
			
		||||
 | 
			
		||||
    // Add new group on the 'Manage display' page.
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/article/display', $group, t('Save'));
 | 
			
		||||
    $this->assertRaw(t('New group %label successfully created.', array('%label' => $this->group_label)), t('Group message displayed on screen.'));
 | 
			
		||||
 | 
			
		||||
    // Test if group is in the $groups array.
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'default', TRUE);
 | 
			
		||||
    $this->assertTrue(array_key_exists($this->group_name, $groups), t('Group found in groups array'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Delete a group.
 | 
			
		||||
   */
 | 
			
		||||
  function deleteGroup() {
 | 
			
		||||
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/article/groups/' . $this->group_name . '/delete/form', array(), t('Delete'));
 | 
			
		||||
    $this->assertRaw(t('The group %label has been deleted from the %article content type.', array('%label' => $this->group_label, '%article' => 'Article')), t('Group removal message displayed on screen.'));
 | 
			
		||||
 | 
			
		||||
    // Test that group is not in the $groups array.
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'form', TRUE);
 | 
			
		||||
    $this->assertFalse(array_key_exists($this->group_name, $groups), t('Group not found in groups array while deleting'));
 | 
			
		||||
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/article/groups/' . $this->group_name . '/delete/default', array(), t('Delete'));
 | 
			
		||||
    $this->assertRaw(t('The group %label has been deleted from the %article content type.', array('%label' => $this->group_label, '%article' => 'Article')), t('Group removal message displayed on screen.'));
 | 
			
		||||
 | 
			
		||||
    // Test that group is not in the $groups array.
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'default', TRUE);
 | 
			
		||||
    $this->assertFalse(array_key_exists($this->group_name, $groups), t('Group not found in groups array while deleting'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * General CRUD.
 | 
			
		||||
   */
 | 
			
		||||
  function testCRUDGroup() {
 | 
			
		||||
    $this->createGroup();
 | 
			
		||||
    $this->deleteGroup();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Nest a field underneath a group.
 | 
			
		||||
   */
 | 
			
		||||
  function testNestField() {
 | 
			
		||||
 | 
			
		||||
    $this->createGroup();
 | 
			
		||||
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'fields[field_image][parent]' => $this->group_name,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/article/fields', $edit, t('Save'));
 | 
			
		||||
    $this->assertRaw(t('Your settings have been saved.'), t('Settings saved'));
 | 
			
		||||
 | 
			
		||||
    $groups = field_group_info_groups('node', 'article', 'form', TRUE);
 | 
			
		||||
    $this->assertTrue(in_array('field_image', $groups[$this->group_name]->children), t('Image is a child of %group', array('%group' => $this->group_name)));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
name = "Fieldgroup Test"
 | 
			
		||||
description = "Test module for fieldgroup"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
package = "Fieldgroup"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; Information added by drupal.org packaging script on 2013-09-25
 | 
			
		||||
version = "7.x-1.3"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "field_group"
 | 
			
		||||
datestamp = "1380124361"
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,17 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Fieldgroup test module.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_access().
 | 
			
		||||
 */
 | 
			
		||||
function field_group_test_field_access($op, $field, $entity_type, $entity, $account) {
 | 
			
		||||
  // Set access to false for field_no_access.
 | 
			
		||||
  if ($op == 'view' && $field['field_name'] == 'field_no_access') {
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user