{***************************************************************************}
{ TMS IntraWeb Component Pack Pro                                           }
{ for Delphi & C++Builder                                                   }
{                                                                           }
{ written by TMS Software                                                   }
{            copyright © 2002 - 2007                                        }
{            Email : info@tmssoftware.com                                   }
{            Web : http://www.tmssoftware.com                               }
{                                                                           }
{ The source code is given as is. The author is not responsible             }
{ for any possible damage done due to the use of this code.                 }
{ The component can be freely used in any application. The complete         }
{ source code remains property of the author and may not be distributed,    }
{ published, given or sold in any form as such. No parts of the source      }
{ code can be included in any other component or application without        }
{ written authorization of the author.                                      }
{***************************************************************************}

unit IWTMSLinks;

{$I TMSDEFS.INC}

interface

uses
  {$IFNDEF LINUX}
  Windows,
  {$ENDIF}
  {$IFDEF DELPHI6_LVL}
  Types,
  {$ENDIF}
  Classes,
  IWControl, IWTypes, SysUtils, IWCompButton,
  IWCompEdit, IWCompLabel, IWCompCheckbox, IWExtCtrls, IWHTMLTag, IWCompListbox,
  IWTMSBase
  {$IFDEF TMSIW6}
  , IWRenderContext
  {$ENDIF}
  ;

type
  TDragDropMode = (ddCopy,ddMove);

  TTIWListLink = class(TIWControl)
  private
    FMoveLR:TIWButton;
    FMoveAllLR: TIWButton;
    FMoveRL:TIWButton;
    FMoveAllRL: TIWButton;
    FCopyLR:TIWButton;
    FCopyRL:TIWButton;
    FLList:TIWListBox;
    FRList:TIWListBox;
    FSort: Boolean;

    procedure SetMoveLR(AButton:TIWButton);
    procedure SetMoveAllLR(AButton:TIWButton);
    procedure SetMoveRL(AButton:TIWButton);
    procedure SetMoveAllRL(AButton:TIWButton);
    procedure SetCopyLR(AButton:TIWButton);
    procedure SetCopyRL(AButton:TIWButton);
    procedure SetLList(alist:TIWListBox);
    procedure SetRList(alist:TIWListBox);
    procedure SetSort(bool: Boolean);
  protected
    procedure SetValue(const AValue: string); override;
    procedure Notification(AComponent: TComponent; AOperation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
    procedure Loaded; override;
    procedure MakeScript;
    {$IFDEF TMSIW6}
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
    {$ELSE}
    function RenderHTML: TIWHTMLTag; override;
    {$ENDIF}
  published
    property MoveLR:TIWButton read FMoveLR write SetMoveLR;
    property MoveAllLR:TIWButton read FMoveAllLR write SetMoveAllLR;
    property MoveRL:TIWButton read FMoveRL write SetMoveRL;
    property MoveAllRL:TIWButton read FMoveAllRL write SetMoveAllRL;
    property CopyLR:TIWButton read FCopyLR write SetCopyLR;
    property CopyRL:TIWButton read FCopyRL write SetCopyRL;
    property LList:TIWListBox read FLList write SetLList;
    property RList:TIWListBox read FRList write SetRList;
    property Sort: Boolean read FSort write SetSort;
  end;

  TTIWComboListLink = class(TIWControl)
  private
    FMoveLR:TIWButton;
    FMoveAllLR: TIWButton;
    FMoveRL:TIWButton;
    FMoveAllRL: TIWButton;
    FCopyLR:TIWButton;
    FCopyRL:TIWButton;
    FLCombo:TIWComboBox;
    FRList:TIWListBox;
    FSort: Boolean;

    procedure SetMoveLR(AButton:TIWButton);
    procedure SetMoveAllLR(AButton:TIWButton);
    procedure SetMoveRL(AButton:TIWButton);
    procedure SetMoveAllRL(AButton:TIWButton);
    procedure SetCopyLR(AButton:TIWButton);
    procedure SetCopyRL(AButton:TIWButton);
    procedure SetLCombo(acombo:TIWComboBox);
    procedure SetRList(alist:TIWListBox);
    procedure SetSort(bool: Boolean);
  protected
    procedure SetValue(const AValue: string); override;
    procedure Notification(AComponent: TComponent; AOperation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
    procedure Loaded; override;
    procedure MakeScript;
    {$IFDEF TMSIW6}
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
    {$ELSE}
    function RenderHTML: TIWHTMLTag; override;
    {$ENDIF}
  published
    property MoveLR:TIWButton read FMoveLR write SetMoveLR;
    property MoveAllLR:TIWButton read FMoveAllLR write SetMoveAllLR;
    property MoveRL:TIWButton read FMoveRL write SetMoveRL;
    property MoveAllRL:TIWButton read FMoveAllRL write SetMoveAllRL;
    property CopyLR:TIWButton read FCopyLR write SetCopyLR;
    property CopyRL:TIWButton read FCopyRL write SetCopyRL;
    property LCombo:TIWComboBox read FLCombo write SetLCombo;
    property RList:TIWListBox read FRList write SetRList;
    property Sort: Boolean read FSort write SetSort;
  end;

  {$IFNDEF TMSIW6}
   TIWCustomControl = class(TIWControl)
   end;
  {$ENDIF}

  TTIWEditListLink = class(TIWControl)
  private
    FMoveEditList:TIWButton;
    FDeleteSelectedItem: TIWButton;
    FLEdit:TIWCustomControl;
    FRList:TIWListBox;
    FSort: Boolean;

    procedure SetMoveEditList(AButton:TIWButton);
    procedure SetDeleteSelectedItem(AButton:TIWButton);
    procedure SetLEdit(anEdit:TIWCustomControl);
    procedure SetRList(alist:TIWListBox);
    procedure SetSort(bool: Boolean);
  protected
    procedure SetValue(const AValue: string); override;
    procedure Notification(AComponent: TComponent; AOperation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
    procedure Loaded; override;
    procedure MakeScript;
    {$IFDEF TMSIW6}
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
    {$ELSE}
    function RenderHTML: TIWHTMLTag; override;
    {$ENDIF}
  published
    property MoveEditList:TIWButton read FMoveEditList write SetMoveEditList;
    property DeleteSelectedItem:TIWButton read FDeleteSelectedItem write SetDeleteSelectedItem;
    property LEdit: TIWCustomControl read FLEdit write SetLEdit;
    property RList:TIWListBox read FRList write SetRList;
    property Sort: Boolean read FSort write SetSort;
  end;


 TTIWListOrganizer = class(TIWControl)
  private
    FMoveUp:TIWButton;
    FMoveDown: TIWButton;
    FList:TIWListBox;

    procedure SetMoveUp(AButton:TIWButton);
    procedure SetMoveDown(AButton:TIWButton);
    procedure SetList(alist:TIWListBox);
  protected
    procedure SetValue(const AValue: string); override;
    procedure Notification(AComponent: TComponent; AOperation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
    procedure Loaded; override;
    procedure MakeScript;
    {$IFDEF TMSIW6}
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
    {$ELSE}
    function RenderHTML: TIWHTMLTag; override;
    {$ENDIF}
  published
    property MoveUp:TIWButton read FMoveUp write SetMoveUp;
    property MoveDown:TIWButton read FMoveDown write SetMoveDown;
    property List:TIWListBox read FList write SetList;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('TMS IW',[TTIWListLink]);
  RegisterComponents('TMS IW',[TTIWComboListLink]);
  RegisterComponents('TMS IW',[TTIWEditListLink]);
  RegisterComponents('TMS IW',[TTIWListOrganizer]);
end;

{ TTIWListLink }
constructor TTIWListLink.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  {$IFDEF TMSIW6}
  {TODO}
  {$ELSE}
  FSupportsSubmit := True;
  FSupportsInput := True;
  {$ENDIF}
  FSort := false;
end;

destructor TTIWListLink.Destroy;
begin
  inherited;
end;

procedure TTIWListLink.Notification(AComponent: TComponent;
  AOperation: TOperation);
begin
  inherited;
  if (AOperation = opRemove) and (AComponent = FMoveLR) then
    FMoveLR := nil;

  if (AOperation = opRemove) and (AComponent = FMoveRL) then
    FMoveRL := nil;

  if (AOperation = opRemove) and (AComponent = FMoveAllLR) then
    FMoveAllLR := nil;

  if (AOperation = opRemove) and (AComponent = FMoveAllRL) then
    FMoveAllRL := nil;

  if (AOperation = opRemove) and (AComponent = FCopyLR) then
    FCopyLR := nil;

  if (AOperation = opRemove) and (AComponent = FCopyRL) then
    FCopyRL := nil;

  if (AOperation = opRemove) and (AComponent = FLList) then
    FLList := nil;

  if (AOperation = opRemove) and (AComponent = FRList) then
    FRlist := nil;
end;

procedure TTIWListLink.Loaded;
begin
  inherited;
  if not (csDesigning in ComponentState) then
  begin
    MakeScript;
  end;
end;

procedure TTIWListLink.MakeScript;
var
  i,indexOnClick: integer;
begin
  {MoveLR}
  if Assigned(FMoveLR) then
  begin
    indexOnClick := 0;
    if (FMoveLR.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveLR.ScriptEvents.Count -1 do
      begin
        if (FMoveLR.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveLR.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveLR.ScriptEvents.Add('onClick');
    FMoveLR.ScriptEvents.HookEvent('onClick',HTMLName+'MoveLR("move")');
  end;

  {MoveAllLR}
  if Assigned(FMoveAllLR) then
  begin
    indexOnClick := 0;
    if (FMoveAllLR.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveAllLR.ScriptEvents.Count -1 do
      begin
        if (FMoveAllLR.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveAllLR.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveAllLR.ScriptEvents.Add('onClick');
    FMoveAllLR.ScriptEvents.HookEvent('onClick',HTMLName+'MoveAllLR()');
  end;

  {MoveRL}
  if Assigned(FMoveRL) then
  begin
    indexOnClick := 0;
    if (FMoveRL.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveRL.ScriptEvents.Count -1 do
      begin
        if (FMoveRL.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveRL.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveRL.ScriptEvents.Add('onClick');
    FMoveRL.ScriptEvents.HookEvent('onClick',HTMLName+'MoveRL("move")');
  end;

  {MoveAllRL}
  if Assigned(FMoveAllRL) then
  begin
    indexOnClick := 0;
    if (FMoveAllRL.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveAllRL.ScriptEvents.Count -1 do
      begin
        if (FMoveAllRL.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveAllRL.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveAllRL.ScriptEvents.Add('onClick');
    FMoveAllRL.ScriptEvents.HookEvent('onClick',HTMLName+'MoveAllRL()');
  end;

  {CopyLR}
  if Assigned(FCopyLR) then
  begin
    indexOnClick := 0;
    if (FCopyLR.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FCopyLR.ScriptEvents.Count -1 do
      begin
        if (FCopyLR.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FCopyLR.ScriptEvents.Delete(indexOnClick);
    end;
    FCopyLR.ScriptEvents.Add('onClick');
    FCopyLR.ScriptEvents.HookEvent('onClick',HTMLName+'MoveLR("copy")');
  end;

  {CopyRL}
  if Assigned(FCopyRL) then
  begin
    indexOnClick := 0;
    if (FCopyRL.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FCopyRL.ScriptEvents.Count -1 do
      begin
        if (FCopyRL.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FCopyRL.ScriptEvents.Delete(indexOnClick);
    end;
    FCopyRL.ScriptEvents.Add('onClick');
    FCopyRL.ScriptEvents.HookEvent('onClick',HTMLName+'MoveRL("copy")');
  end;
end;

procedure TTIWListLink.SetCopyLR(AButton: TIWButton);
begin
  FCopyLR := AButton;
end;

procedure TTIWListLink.SetCopyRL(AButton: TIWButton);
begin
  FCopyRL := AButton;
end;

procedure TTIWListLink.SetMoveAllLR(AButton: TIWButton);
begin
  FMoveAllLR := AButton;
end;

procedure TTIWListLink.SetMoveAllRL(AButton: TIWButton);
begin
  FMoveAllRL := AButton;
end;

procedure TTIWListLink.SetValue(const AValue: string);
var
  sl:tstringlist;
  s:string;
begin
  if (Length(AValue) = 0) or (pos('^',AValue) = 0) then
    Exit;

  if not Assigned(RList) or not Assigned(LList) then
    Exit;

  sl := TStringlist.Create;

  s := copy(AValue,1,pos('^',AValue) - 1);

  while (pos('|',s) > 0) do
  begin
    sl.Add(copy(s,1,pos('|',s) - 1));
    delete(s,1,pos('|',s));
  end;
  if length(s) > 0 then
    sl.Add(s);

  LList.Items.Assign(sl);
  sl.Clear;

  s := copy(AValue,pos('^',AValue) + 1,Length(AValue));

  while (pos('|',s) > 0) do
  begin
    sl.Add(copy(s,1,pos('|',s) - 1));
    delete(s,1,pos('|',s));
  end;
  if length(s) > 0 then
    sl.Add(s);

  RList.Items.Assign(sl);

  RList.ItemIndex := 0;
  LList.ItemIndex := 0;

  sl.Free;
end;

{$IFDEF TMSIW6}
function TTIWListLink.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
{$ELSE}
function TTIWListLink.RenderHTML: TIWHTMLTag;
{$ENDIF}
var
 LJScript: TStrings;
begin
  LJScript := TStringList.Create;
  try
    with LJScript do begin
      {send the content back to the server}
      Add('function '+ HTMLName + 'BuildLists() {');
      Add('lbF = document.getElementById("'+LList.HTMLName+'");');
      Add('lbT = document.getElementById("'+RList.HTMLName+'");');
      Add('sf = "";');
      Add('st = "";');
      Add('for(i=0;i<lbF.options.length;i++){');
      Add(' if (i>0) ');
      Add('  sf = sf + "|";');
      if (LList.ItemsHaveValues) then
        Add('  sf = sf + lbF.options[i].text + "=" + lbF.options[i].value;')
      else
        Add('  sf = sf + lbF.options[i].text;');
      Add('}');
      Add('for(i=0;i<lbT.options.length;i++){');
      Add(' if (i>0) ');
      Add('  st = st + "|";');
      if (RList.ItemsHaveValues) then
        Add('  st = st + lbT.options[i].text + "=" + lbT.options[i].value;')
      else
        Add('  st = st + lbT.options[i].text;');
      Add('}');
      Add('FindElem("'+HTMLName+'").value = sf + "^" + st;');
      Add('}');

      Add('function '+HTMLName + 'deleteOption(object,index) {');
      Add('object.options[index] = null;');
      Add('}');

      Add('function '+ HTMLName +'addOption(object,text,value) {');
      Add('var defaultSelected = false;');
      Add('var selected = false;');
      Add('var optionName = new Option(text, value, defaultSelected, selected)');
      Add('object.options[object.length] = optionName;');
      Add('object.options[object.length-1].selected = false;');
      Add('}');

      Add('function ' + HTMLName + 'SortOptions(what){');
      Add('var copyOption = new Array();');
      Add('for (var i=0;i<what.options.length;i++)');
      Add('copyOption[i] = new Array(what[i].text,what[i].value);');
      Add('copyOption.sort();');
      Add('for (var i=what.options.length-1;i>-1;i--)');
      Add(HTMLName+'deleteOption(what,i);');
      Add('for (var i=0;i<copyOption.length;i++)');
      Add(HTMLName+'addOption(what,copyOption[i][0],copyOption[i][1])');
      Add('}');

      {Function Move}
      Add('function '+ HTMLName + 'Move(lb1,lb2){');
      Add('trash = new Array();');
      Add('var flag = true;');

      Add('for(var i=0;i<lb1.options.length;i++){');
      Add('for(var j=0;j<lb2.options.length;j++){');
      Add('if((lb1.options[i].selected)&&(lb1.options[i].text == lb2.options[j].text)){');
      Add('flag = false;');
      Add('break;');
      Add('}');
      Add('}');
      //Add('if(!flag)break;');
      Add('}');
      //Add('if(flag){');
      {Move element}

      Add('for(var i=0;i<lb1.options.length;i++){');
      Add('if(lb1.options[i].selected){');
      Add('if(flag)');
      Add('  lb2.options[lb2.options.length] = new Option(lb1.options[i].text,lb1.options[i].value, false, false);');
      Add('trash[trash.length] = i;');
      Add('}');
      Add('}');

      Add('for(var i=trash.length-1;i>-1;i--){');
      Add('lb1.options[trash[i]] = null;');
      Add('}');

      //Add('}');
      Add('lb1.selectedIndex = -1;');
      Add('lb2.selectedIndex = -1;');
      Add('}');

      {Function Copy}
      Add('function '+ HTMLName + 'Copy(lb1,lb2){');
      Add('trash = new Array();');
      Add('var flag = true;');

      Add('for(var i=0;i<lb1.options.length;i++){');
      Add('for(var j=0;j<lb2.options.length;j++){');
      Add('if((lb1.options[i].selected)&&(lb1.options[i].text == lb2.options[j].text)){');
      Add('flag = false;');
      Add('break;');
      Add('}');
      Add('}');
      Add('if(!flag)break;');
      Add('}');
      Add('if(flag){');
      {Move element}
      Add('for(var i=0;i<lb1.options.length;i++){');
      Add('if(lb1.options[i].selected){');
      Add('lb2.options[lb2.options.length] = new Option(lb1.options[i].text,lb1.options[i].value, false, false);');
      Add('trash[trash.length] = i;');
      Add('}');
      Add('}');
      Add('}');
      Add('lb1.selectedIndex = -1;');
      Add('lb2.selectedIndex = -1;');
      Add('}');

      {Function MoveAll}
      Add('function '+ HTMLName + 'MoveAll(lb1,lb2){');
      Add('trash = new Array();');
      Add('var flag = true;');
      Add('var twice = false;');

      {Move all the elements}
      Add('for(var i=0;i<lb2.options.length;i++) {');
      Add('trash[trash.length] = i;');
      Add('}');

      Add('for(var i=0;i<lb1.options.length;i++){');
      Add('twice = false;');
      Add('for(var j=0;j<lb2.options.length;j++) {');
      Add('if (lb1.options[i].text == lb2.options[j].text){');
      Add('twice = true;');
      Add('}');
      Add('}');

      Add('if(!twice){');
      Add('lb2.options[lb2.options.length] = new Option(lb1.options[i].text,lb1.options[i].value, false, false);');
      Add('trash[trash.length] = i;');
      Add('}');
      Add('}');
      Add('for(var i=trash.length-1;i>-1;i--){');
      Add('lb1.options[trash[i]] = null;');
      Add('}');

      Add('lb1.selectedIndex = -1;');
      Add('lb2.selectedIndex = -1;');
      Add(HTMLName+'BuildLists();');
      Add('}');

      {Function MoveLR}
      Add('function '+ HTMLName + 'MoveLR(state){');

      Add('lbF = document.getElementById("'+LList.HTMLName+'");');
      Add('lbT = document.getElementById("'+RList.HTMLName+'");');
      Add('var status = state');
      Add('if (status == "move") {');
      Add(HTMLName+'Move(lbF,lbT)}');
      Add('else {');
      Add(HTMLName+'Copy(lbF,lbT)');
      Add('}');
      if (FSort) then
        Add(HTMLName + 'SortOptions(lbT);');
      Add(HTMLName+'BuildLists();');
      Add('}');

      {Function MoveAllLR}
      Add('function '+ HTMLName + 'MoveAllLR(){');
      Add('lbF = document.getElementById("'+LList.HTMLName+'");');
      Add('lbT = document.getElementById("'+RList.HTMLName+'");');
      Add(HTMLName+'MoveAll(lbF,lbT)');
      if (FSort) then
        Add(HTMLName + 'SortOptions(lbT);');
      Add(HTMLName+'BuildLists();');
      Add('}');

      {Function MoveRL}
      Add('function '+ HTMLName + 'MoveRL(state){');

      Add('lbT = document.getElementById("'+LList.HTMLName+'");');
      Add('lbF = document.getElementById("'+RList.HTMLName+'");');
      Add('var status = state');
      Add('if (status == "move") {');
      Add(HTMLName+'Move(lbF,lbT)}');
      Add('else {');
      Add(HTMLName+'Copy(lbF,lbT)');
      Add('}');
      if (FSort) then
        Add(HTMLName + 'SortOptions(lbT);');
      Add(HTMLName+'BuildLists();');
      Add('}');

      {Function MoveAllRL}
      Add('function '+ HTMLName + 'MoveAllRL(){');

      Add('lbT = document.getElementById("'+LList.HTMLName+'");');
      Add('lbF = document.getElementById("'+RList.HTMLName+'");');
      Add(HTMLName+'MoveAll(lbF,lbT)');
      if (FSort) then
        Add(HTMLName + 'SortOptions(lbT);');
      Add(HTMLName+'BuildLists();');
      Add('}');
    end;
    {$IFDEF TMSIW6}
    TIWComponent40Context(AContext).AddToJavaScriptOnce(LJScript.Text);
    {$ELSE}
    AddToJavaScriptOnce(LJScript.Text);
    {$ENDIF}
  finally
    FreeAndNil(LJSCript);
  end;

  Result := TIWHTMLTag.CreateTag('DIV');
  with Result.Contents.AddTag('INPUT') do
  begin
    AddStringParam('TYPE','HIDDEN');
    AddStringParam('NAME',HTMLName);
    AddStringParam('ID',HTMLName+'_INPUT');
  end;

end;

procedure TTIWListLink.SetSort(bool: Boolean);
begin
  FSort := bool;
end;

procedure TTIWListLink.SetLList(alist: TIWListBox);
begin
  FLList := alist;
end;

procedure TTIWListLink.SetMoveLR(AButton: TIWButton);
begin
  FMoveLR := AButton;
end;

procedure TTIWListLink.SetMoveRL(AButton: TIWButton);
begin
  FMoveRL := AButton;
end;

procedure TTIWListLink.SetRList(alist: TIWListBox);
begin
  FRList := alist;
end;

{ TTIWComboListLink }

constructor TTIWComboListLink.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  {$IFDEF TMSIW6}
  {TODO}
  {$ELSE}
  FSupportsSubmit := True;
  FSupportsInput := True;
  {$ENDIF}
  FSort := false;
end;

destructor TTIWComboListLink.Destroy;
begin

  inherited;
end;

procedure TTIWComboListLink.Loaded;
begin
  inherited;
  if not (csDesigning in ComponentState) then
  begin
    MakeScript;
  end;
end;

procedure TTIWComboListLink.MakeScript;
var
  i,indexOnClick: integer;
begin
  {MoveLR}
  if Assigned(FMoveLR) then
  begin
    indexOnClick := 0;
    if (FMoveLR.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveLR.ScriptEvents.Count -1 do
      begin
        if (FMoveLR.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveLR.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveLR.ScriptEvents.Add('onClick');
    FMoveLR.ScriptEvents.HookEvent('onClick',HTMLName+'MoveLR("move")');
  end;

  {MoveAllLR}
  if Assigned(FMoveAllLR) then
  begin
    indexOnClick := 0;
    if (FMoveAllLR.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveAllLR.ScriptEvents.Count -1 do
      begin
        if (FMoveAllLR.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveAllLR.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveAllLR.ScriptEvents.Add('onClick');
    FMoveAllLR.ScriptEvents.HookEvent('onClick',HTMLName+'MoveAllLR()');
  end;

  {MoveRL}
  if Assigned(FMoveRL) then
  begin
    indexOnClick := 0;
    if (FMoveRL.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveRL.ScriptEvents.Count -1 do
      begin
        if (FMoveRL.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveRL.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveRL.ScriptEvents.Add('onClick');
    FMoveRL.ScriptEvents.HookEvent('onClick',HTMLName+'MoveRL("move")');
  end;

  {MoveAllRL}
  if Assigned(FMoveAllRL) then
  begin
    indexOnClick := 0;
    if (FMoveAllRL.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveAllRL.ScriptEvents.Count -1 do
      begin
        if (FMoveAllRL.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveAllRL.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveAllRL.ScriptEvents.Add('onClick');
    FMoveAllRL.ScriptEvents.HookEvent('onClick',HTMLName+'MoveAllRL()');
  end;

  {CopyLR}
  if Assigned(FCopyLR) then
  begin
    indexOnClick := 0;
    if (FCopyLR.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FCopyLR.ScriptEvents.Count -1 do
      begin
        if (FCopyLR.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FCopyLR.ScriptEvents.Delete(indexOnClick);
    end;
    FCopyLR.ScriptEvents.Add('onClick');
    FCopyLR.ScriptEvents.HookEvent('onClick',HTMLName+'MoveLR("copy")');
  end;

  {CopyRL}
  if Assigned(FCopyRL) then
  begin
    indexOnClick := 0;
    if (FCopyRL.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FCopyRL.ScriptEvents.Count -1 do
      begin
        if (FCopyRL.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FCopyRL.ScriptEvents.Delete(indexOnClick);
    end;
    FCopyRL.ScriptEvents.Add('onClick');
    FCopyRL.ScriptEvents.HookEvent('onClick',HTMLName+'MoveRL("copy")');
  end;
end;

procedure TTIWComboListLink.Notification(AComponent: TComponent;
  AOperation: TOperation);
begin
  inherited;
  if (AOperation = opRemove) and (AComponent = FMoveLR) then
    FMoveLR := nil;

  if (AOperation = opRemove) and (AComponent = FMoveRL) then
    FMoveRL := nil;

  if (AOperation = opRemove) and (AComponent = FMoveAllLR) then
    FMoveAllLR := nil;

  if (AOperation = opRemove) and (AComponent = FMoveAllRL) then
    FMoveAllRL := nil;

  if (AOperation = opRemove) and (AComponent = FCopyLR) then
    FCopyLR := nil;

  if (AOperation = opRemove) and (AComponent = FCopyRL) then
    FCopyRL := nil;

  if (AOperation = opRemove) and (AComponent = FLCombo) then
    FLCombo := nil;

  if (AOperation = opRemove) and (AComponent = FRList) then
    FRlist := nil;
end;

{$IFDEF TMSIW6}
function TTIWComboListLink.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
{$ELSE}
function TTIWComboListLink.RenderHTML: TIWHTMLTag;
{$ENDIF}
var
 LJScript: TStrings;
begin
  LJScript := TStringList.Create;
  try
    with LJScript do begin
      {send the content back to the server}
      Add('function '+ HTMLName + 'BuildLists() {');
      Add('cbF = document.getElementById("'+LCombo.HTMLName+'");');
      Add('lbT = document.getElementById("'+RList.HTMLName+'");');
      Add('sf = "";');
      Add('st = "";');
      Add('for(i=0;i<cbF.options.length;i++){');
      Add(' if (i>0) ');
      Add('  sf = sf + "|";');
      if (LCombo.ItemsHaveValues) then
        Add('  sf = sf + cbF.options[i].text + "=" + cbF.options[i].value;')
      else
        Add('  sf = sf + cbF.options[i].text;');
      Add('}');
      Add('for(i=0;i<lbT.options.length;i++){');
      Add(' if (i>0) ');
      Add('  st = st + "|";');
      if (RList.ItemsHaveValues) then
        Add('  st = st + lbT.options[i].text + "=" + lbT.options[i].value;')
      else
        Add('  st = st + lbT.options[i].text;');
      Add('}');
      Add('FindElem("'+HTMLName+'").value = sf + "^" + st;');
      Add('}');

      Add('function '+HTMLName + 'deleteOption(object,index) {');
      Add('object.options[index] = null;');
      Add('}');

      Add('function '+ HTMLName +'addOption(object,text,value) {');
      Add('var defaultSelected = false;');
      Add('var selected = false;');
      Add('var optionName = new Option(text, value, defaultSelected, selected)');
      Add('object.options[object.length] = optionName;');
      Add('object.options[object.length-1].selected = false;');
      Add('}');

      Add('function ' + HTMLName + 'SortOptions(what){');
      Add('var copyOption = new Array();');
      Add('for (var i=0;i<what.options.length;i++)');
      Add('copyOption[i] = new Array(what[i].text,what[i].value);');
      Add('copyOption.sort();');
      Add('for (var i=what.options.length-1;i>-1;i--)');
      Add(HTMLName+'deleteOption(what,i);');
      Add('for (var i=0;i<copyOption.length;i++)');
      Add(HTMLName+'addOption(what,copyOption[i][0],copyOption[i][1])');
      Add('}');

      {Function Move}
      Add('function '+ HTMLName + 'Move(cb1,lb2){');
      Add('trash = new Array();');
      Add('var flag = true;');

      Add('for(var i=0;i<cb1.options.length;i++){');
      Add('for(var j=0;j<lb2.options.length;j++){');
      Add('if((cb1.options[i].selected)&&(cb1.options[i].text == lb2.options[j].text)){');
      Add('flag = false;');
      Add('break;');
      Add('}');
      Add('}');
      Add('if(!flag)break;');
      Add('}');
      Add('if(flag){');
      {Move element}

      Add('for(var i=0;i<cb1.options.length;i++){');
      Add('if(cb1.options[i].selected){');
      Add('lb2.options[lb2.options.length] = new Option(cb1.options[i].text,cb1.options[i].value, false, false);');
      Add('trash[trash.length] = i;');
      Add('}');
      Add('}');
      Add('for(var i=trash.length-1;i>-1;i--){');
      Add('cb1.options[trash[i]] = null;');
      Add('}');
      Add('}');
      Add('cb1.selectedIndex = -1;');
      Add('lb2.selectedIndex = -1;');
      Add('}');

      {Function Copy}
      Add('function '+ HTMLName + 'Copy(cb1,lb2){');
      Add('trash = new Array();');
      Add('var flag = true;');

      Add('for(var i=0;i<cb1.options.length;i++){');
      Add('for(var j=0;j<lb2.options.length;j++){');
      Add('if((cb1.options[i].selected)&&(cb1.options[i].text == lb2.options[j].text)){');
      Add('flag = false;');
      Add('break;');
      Add('}');
      Add('}');
      Add('if(!flag)break;');
      Add('}');
      Add('if(flag){');
      {Move element}
      Add('for(var i=0;i<cb1.options.length;i++){');
      Add('if(cb1.options[i].selected){');
      Add('lb2.options[lb2.options.length] = new Option(cb1.options[i].text,cb1.options[i].value, false, false);');
      Add('trash[trash.length] = i;');
      Add('}');
      Add('}');
      Add('}');
      Add('cb1.selectedIndex = -1;');
      Add('lb2.selectedIndex = -1;');
      Add('}');

      {Function MoveAll}
      Add('function '+ HTMLName + 'MoveAll(cb1,lb2){');
      Add('trash = new Array();');
      Add('var flag = true;');
      Add('var twice = false;');

      {Move all the elements}
      Add('for(var i=0;i<lb2.options.length;i++) {');
      Add('trash[trash.length] = i;');
      Add('}');

      Add('for(var i=0;i<cb1.options.length;i++){');
      Add('twice = false;');
      Add('for(var j=0;j<lb2.options.length;j++) {');
      Add('if (cb1.options[i].text == lb2.options[j].text){');
      Add('twice = true;');
      Add('}');
      Add('}');

      Add('if(!twice){');
      Add('lb2.options[lb2.options.length] = new Option(cb1.options[i].text,cb1.options[i].value, false, false);');
      Add('trash[trash.length] = i;');
      Add('}');
      Add('}');
      Add('for(var i=trash.length-1;i>-1;i--){');
      Add('cb1.options[trash[i]] = null;');
      Add('}');

      Add('cb1.selectedIndex = -1;');
      Add('lb2.selectedIndex = -1;');
      Add('}');

      {Function MoveLR}
      Add('function '+ HTMLName + 'MoveLR(state){');

      Add('cbF = document.getElementById("'+LCombo.HTMLName+'");');
      Add('lbT = document.getElementById("'+RList.HTMLName+'");');
      Add('var status = state');
      Add('if (status == "move") {');
      Add(HTMLName+'Move(cbF,lbT)}');
      Add('else {');
      Add(HTMLName+'Copy(cbF,lbT)');
      Add('}');
      if (FSort) then
        Add(HTMLName + 'SortOptions(lbT);');
      Add(HTMLName+'BuildLists();');
      Add('}');

      {Function MoveAllLR}
      Add('function '+ HTMLName + 'MoveAllLR(){');
      Add('cbF = document.getElementById("'+LCombo.HTMLName+'");');
      Add('lbT = document.getElementById("'+RList.HTMLName+'");');
      Add(HTMLName+'MoveAll(cbF,lbT)');
      if (FSort) then
        Add(HTMLName + 'SortOptions(lbT);');
      Add(HTMLName+'BuildLists();');
      Add('}');

      {Function MoveRL}
      Add('function '+ HTMLName + 'MoveRL(state){');

      Add('cbT = document.getElementById("'+LCombo.HTMLName+'");');
      Add('lbF = document.getElementById("'+RList.HTMLName+'");');
      Add('var status = state');
      Add('if (status == "move") {');
      Add(HTMLName+'Move(lbF,cbT)}');
      Add('else {');
      Add(HTMLName+'Copy(lbF,cbT)');
      Add('}');
      if (FSort) then
        Add(HTMLName + 'SortOptions(cbT);');

      Add(HTMLName+'BuildLists();');
      Add('}');

      {Function MoveAllRL}
      Add('function '+ HTMLName + 'MoveAllRL(){');

      Add('cbT = document.getElementById("'+LCombo.HTMLName+'");');
      Add('lbF = document.getElementById("'+RList.HTMLName+'");');
      Add(HTMLName+'MoveAll(lbF,cbT)');
      if (FSort) then
        Add(HTMLName + 'SortOptions(cbT);');

      Add(HTMLName+'BuildLists();');
      Add('}');
    end;
    {$IFDEF TMSIW6}
    TIWComponent40Context(AContext).AddToJavaScriptOnce(LJScript.Text);
    {$ELSE}
    AddToJavaScriptOnce(LJScript.Text);
    {$ENDIF}
  finally
    FreeAndNil(LJSCript);
  end;

  Result := TIWHTMLTag.CreateTag('DIV');
  with Result.Contents.AddTag('INPUT') do
  begin
    AddStringParam('TYPE','hidden');
    AddStringParam('NAME',HTMLName);
    AddStringParam('ID',HTMLName+'_INPUT');
  end;
end;

procedure TTIWComboListLink.SetCopyLR(AButton: TIWButton);
begin
  FCopyLR := abutton;
end;

procedure TTIWComboListLink.SetCopyRL(AButton: TIWButton);
begin
  FCopyRL := abutton;
end;

procedure TTIWComboListLink.SetLCombo(acombo: TIWComboBox);
begin
  FLCombo := acombo;
end;

procedure TTIWComboListLink.SetMoveAllLR(AButton: TIWButton);
begin
  FMoveAllLR := abutton;
end;

procedure TTIWComboListLink.SetMoveAllRL(AButton: TIWButton);
begin
  FMoveAllRL := abutton;
end;

procedure TTIWComboListLink.SetMoveLR(AButton: TIWButton);
begin
  FMoveLR := abutton;
end;

procedure TTIWComboListLink.SetMoveRL(AButton: TIWButton);
begin
  FMoveRL := abutton;
end;

procedure TTIWComboListLink.SetRList(alist: TIWListBox);
begin
  FRList := alist;
end;

procedure TTIWComboListLink.SetSort(bool: Boolean);
begin
  FSort := bool;
end;

procedure TTIWComboListLink.SetValue(const AValue: string);
var
  sl:tstringlist;
  s:string;
begin
  if (Length(AValue) = 0) or (pos('^',AValue) = 0) then
    Exit;

  if not Assigned(RList) or not Assigned(LCombo) then
    Exit;

  sl := TStringlist.Create;

  s := copy(AValue,1,pos('^',AValue) - 1);

  while (pos('|',s) > 0) do
  begin
    sl.Add(copy(s,1,pos('|',s) - 1));
    delete(s,1,pos('|',s));
  end;
  if length(s) > 0 then
    sl.Add(s);

  LCombo.Items.Assign(sl);
  sl.Clear;

  s := copy(AValue,pos('^',AValue) + 1,Length(AValue));

  while (pos('|',s) > 0) do
  begin
    sl.Add(copy(s,1,pos('|',s) - 1));
    delete(s,1,pos('|',s));
  end;
  if length(s) > 0 then
    sl.Add(s);

  RList.Items.Assign(sl);

  RList.ItemIndex := 0;
  LCombo.ItemIndex := 0;

  sl.Free;
end;
{ TTIWEditListLink }

constructor TTIWEditListLink.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  {$IFDEF TMSIW6}
  {$ELSE}
  FSupportsSubmit := True;
  FSupportsInput := True;
  {$ENDIF}
  FSort := false;
end;

destructor TTIWEditListLink.Destroy;
begin
  inherited;
end;

procedure TTIWEditListLink.Loaded;
begin
  inherited;
  if not (csDesigning in ComponentState) then
  begin
    MakeScript;
  end;
end;

procedure TTIWEditListLink.MakeScript;
var
  i,indexOnClick: integer;
begin
  {MoveEditList}
  if Assigned(FMoveEditList) then
  begin
    indexOnClick := 0;
    if (FMoveEditList.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveEditList.ScriptEvents.Count -1 do
      begin
        if (FMoveEditList.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveEditList.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveEditList.ScriptEvents.Add('onClick');
    FMoveEditList.ScriptEvents.HookEvent('onClick',HTMLName+'MoveEditList()');
  end;

  {DeleteSelectedItem}
  if Assigned(FDeleteSelectedItem) then
  begin
    indexOnClick := 0;
    if (FDeleteSelectedItem.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FDeleteSelectedItem.ScriptEvents.Count -1 do
      begin
        if (FDeleteSelectedItem.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FDeleteSelectedItem.ScriptEvents.Delete(indexOnClick);
    end;
    FDeleteSelectedItem.ScriptEvents.Add('onClick');
    FDeleteSelectedItem.ScriptEvents.HookEvent('onClick',HTMLName+'DeleteSelectedItem()');
  end;

  if Assigned(LEdit) then
  begin
    LEdit.ExtraTagParams.Add('ondragstart='+ HTMLName + 'setRange()');
    LEdit.ExtraTagParams.Add('ondragleave=' + HTMLName +'cancelEvent()');
    LEdit.ExtraTagParams.Add('onblur='+ HTMLName + 'setCaretToBegin(this)');
  end;

  if Assigned(RList) then
  begin
    RList.ExtraTagParams.Add('ondragenter='+ HTMLName + 'cancelEvent()');
    RList.ExtraTagParams.Add('ondragover='+ HTMLName + 'cancelEvent()');
    RList.ExtraTagParams.Add('ondragleave='+ HTMLName + 'cancelEvent()');
    RList.ExtraTagParams.Add('ondrop='+ HTMLName +'MoveEditList()');
  end;
end;

procedure TTIWEditListLink.SetSort(bool: Boolean);
begin
  FSort := bool;
end;

procedure TTIWEditListLink.Notification(AComponent: TComponent;
  AOperation: TOperation);
begin
  inherited;
  if (AOperation = opRemove) and (AComponent = FMoveEditList) then
    FMoveEditList := nil;

  if (AOperation = opRemove) and (AComponent = FDeleteSelectedItem) then
    FDeleteSelectedItem := nil;

  if (AOperation = opRemove) and (AComponent = FLEdit) then
    FLEdit := nil;

  if (AOperation = opRemove) and (AComponent = FRList) then
    FRlist := nil;
end;

{$IFDEF TMSIW6}
function TTIWEditListLink.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
{$ELSE}
function TTIWEditListLink.RenderHTML: TIWHTMLTag;
{$ENDIF}
var
 LJScript: TStrings;
begin
  LJScript := TStringList.Create;
  try
    if Assigned(LEdit) and Assigned(RList) then
      with LJScript do
      begin
        {variable to get the selected text}
        Add('var ' + HTMLName + 'selectedText = ""');
        Add('var ' + HTMLName + 'dropExecuted');

        Add('function ' + HTMLName + 'cancelEvent() {');
        Add('window.event.returnValue = false;');
        Add('}');

        {remove the blanks before the text}
        Add('function ' + HTMLName + 'removeBlanksBefore(s) {');
        Add('var temp = s;');
        Add('var i = 0');
        Add('while(s.charAt(i) == " ") {');
        Add('temp = temp.substring(1,temp.length);');
        Add('i++');
        Add('}');
        Add('return temp');
        Add('}');

        {remove the blanks after the text}
        Add('function ' + HTMLName + 'removeBlanksAfter(s) {');
        Add('var temp=s;');
        Add('var i = temp.length-1;');
        Add('while(s.charAt(i) == " ") {');
        Add('temp = temp.substring(0,temp.length-1);');
        Add('i--');
        Add('}');
        Add('return temp');
        Add('}');

        {send the content back to the server}
        Add('function '+ HTMLName + 'BuildLists() {');
        Add('lbT = FindElem("'+RList.HTMLName+'");');
        //Modified 19/07/2004
        Add('st = "L" + lbT.options.length + "#";');
        Add('for(i=0;i<lbT.options.length;i++){');
        Add(' if (i>0)');
        Add('  st = st + "|"');
        if (RList.ItemsHaveValues) then
          Add('  st = st + lbT.options[i].text + "=" + lbT.options[i].value;')
        else
          Add('  st = st + lbT.options[i].text;');
        //End Modified
        Add('}');
        Add('FindElem("'+HTMLName+'").value = st;');
        Add('}');

        {used by function SortOptions to delete the non-sorted items}
        Add('function '+HTMLName + 'deleteOption(object,index) {');
        Add('object.options[index] = null;');
        Add('}');

        {used by function SortOptions to add the sorted items}
        Add('function '+ HTMLName +'addOption(object,text,value) {');
        Add('var defaultSelected = false;');
        Add('var selected = false;');
        Add('var optionName = new Option(text, value, defaultSelected, selected)');
        Add('object.options[object.length] = optionName;');
        Add('object.options[object.length-1].selected = false;');
        Add('}');

        {add the items in the listbox}
        Add('function ' + HTMLName + 'SortOptions(what){');
        Add('var copyOption = new Array();');
        Add('for (var i=0;i<what.options.length;i++)');
        Add('copyOption[i] = new Array(what[i].text,what[i].value);');
        Add('copyOption.sort();');
        Add('for (var i=what.options.length-1;i>-1;i--)');
        Add(HTMLName+'deleteOption(what,i);');
        Add('for (var i=0;i<copyOption.length;i++)');
        Add(HTMLName+'addOption(what,copyOption[i][0],copyOption[i][1])');
        Add('}');

        {Move the text in the edit control to the listbox}
        Add('function '+ HTMLName + 'MoveEditList(){');
        Add('editF = FindElem("'+LEdit.HTMLName+'");');
        Add('lbT = FindElem("'+RList.HTMLName+'");');
        Add('trash = new Array();');
        Add('var flag = true;');
        Add('if(editF.value.length == 0) {');
        Add('flag = false');
        Add('}');
        Add(' else {');
        Add('if ((typeof(' + HTMLName + 'selectedText) != "undefined") & (' + HTMLName + 'selectedText != "")){');
        Add('val = ' + HTMLName + 'selectedText');
        Add('val =' + HTMLName + 'removeBlanksBefore(val)');
        Add('val =' + HTMLName + 'removeBlanksAfter(val)');
        Add('}');
        Add('else {');
        Add('var val =' + HTMLName + 'removeBlanksBefore(editF.value)');
        Add('val =' + HTMLName + 'removeBlanksAfter(val)');
        Add('}');
        Add('for(var j=0;j<lbT.options.length;j++){');
        Add('if(val == lbT.options[j].text){');
        Add('flag = false;');
        Add('break;');
        Add('}');
        Add('}');
        Add('}');

        Add('if(flag){');
        {Move element}
        Add('var textAfter;');
        Add('var posSelection');
        Add('lbT.options[lbT.options.length] = new Option(val,val, false, false);');
        Add('}');
        Add('lbT.selectedIndex = -1;');
        Add('if (' + HTMLName + 'selectedText == "") {');
        Add('editF.value = "";');
        Add('}');
        Add('else {');
        Add('val = editF.value;');
        Add('posSelection = val.indexOf(' + HTMLName + 'selectedText);');
        Add('textAfter = val.substring(0,posSelection);');
        Add('textAfter = textAfter + val.substring(posSelection + ' + HTMLName + 'selectedText.length, val.length);');
        Add('editF.value = textAfter;');
        Add('}');
        Add(HTMLName + 'setRange()');
        if (FSort) then
          Add(HTMLName+'SortOptions(lbT);');
        Add('lbT.focus();');
        Add(HTMLName+'BuildLists();');
        Add(HTMLName + 'dropExecuted = true;');
        Add('}');

        {Delete the item selected in the listbox}
        Add('function '+ HTMLName + 'DeleteSelectedItem(){');
        Add('editF = FindElem("'+LEdit.HTMLName+'");');
        Add('lbT = FindElem("'+RList.HTMLName+'");');
        Add('trash = new Array();');
        Add('var flag = true;');

        Add('for(i=0;i<lbT.options.length;i++){');
        Add('if (lbT.options[i].selected) {');
        Add('lbT.options[i] = null');
        Add('}');
        Add('}');

        Add('lbT.selectedIndex = 0;');
        Add(HTMLName+'BuildLists();');
        Add('}');

        {set the caret to the begin of the edit control}
        Add('function '+ HTMLName + 'setCaretToBegin(editF) {');
        Add('  if (' + HTMLName + 'dropExecuted) {');
        Add('    if (editF.createTextRange) {');
        Add('      var v = editF.value;');
        Add('      var r = editF.createTextRange();');
        Add('      r.moveEnd('#39 + 'character' + #39 + ', -v.length);');
        Add('      r.select();');
        Add('    }');
        Add('    editF.focus();');
        Add(     HTMLName + 'dropExecuted = false');
        Add('  }');
        Add('}');

        {set the selected text}
        Add('function '+ HTMLName + 'setRange() {');
        Add('if (document.selection) {');
        Add('var range = document.selection.createRange();');
        Add(HTMLName + 'selectedText = range.text;');
        Add('}');
        Add('}');
      end;
    {$IFDEF TMSIW6}
    TIWComponent40Context(AContext).AddToJavaScriptOnce(LJScript.Text);
    {$ELSE}
    AddToJavaScriptOnce(LJScript.Text);
    {$ENDIF}
  finally
    FreeAndNil(LJSCript);
  end;

  Result := TIWHTMLTag.CreateTag('DIV');
  with Result.Contents.AddTag('INPUT') do
  begin
    AddStringParam('TYPE','hidden');
    AddStringParam('NAME',HTMLName);
    AddStringParam('ID',HTMLName+'_INPUT');
  end;
end;

procedure TTIWEditListLink.SetDeleteSelectedItem(AButton: TIWButton);
begin
  FDeleteSelectedItem := AButton;
end;

procedure TTIWEditListLink.SetLEdit(anEdit: TIWCustomControl);
begin
  FLEdit := anEdit;
end;

procedure TTIWEditListLink.SetMoveEditList(AButton: TIWButton);
begin
  FMoveEditList := AButton;
end;

procedure TTIWEditListLink.SetRList(alist: TIWListBox);
begin
  FRList := alist;
end;

procedure TTIWEditListLink.SetValue(const AValue: string);
var
  sl:tstringlist;
  s:string;
  i : integer;
  temp : string;
  //NumberOfItems : integer;
begin
  //Modified on 09/29/2003
  temp := AValue;
  if (Length(temp) = 0) then
    Exit;

  //NumberOfItems :=  StrToInt(Copy(temp,2,pos('#',temp)-2));
  delete(temp,1,pos('#',temp));
  {
  if (Length(AValue) = 0) then
  begin
    Exit;
  end;
  }
  if (Length(temp) = 0) then
  begin
    for i := 0 to RLIst.Items.Count-1 do
      RList.Items.Delete(0);
    Exit;
  end;
  //End Modified

  if not Assigned(RList) or not Assigned(LEdit) then
    Exit;

  sl := TStringlist.Create;

  //Modified 09/29/2003
  //s := copy(AValue,1,Length(AValue));
  s := copy(temp,1,Length(temp));
  //End Modified

  while (pos('|',s) > 0) do
  begin
    sl.Add(copy(s,1,pos('|',s) - 1));
    delete(s,1,pos('|',s));
  end;
  if length(s) > 0 then
    sl.Add(s);

  RList.Items.Assign(sl);
  RList.ItemIndex := 0;
  sl.Free;
end;


{ TTIWListOrganizer }

constructor TTIWListOrganizer.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  {$IFDEF TMSIW6}
  {$ELSE}
  FSupportsSubmit := True;
  FSupportsInput := True;
  {$ENDIF}
end;

destructor TTIWListOrganizer.Destroy;
begin
  inherited;
end;

procedure TTIWListOrganizer.Notification(AComponent: TComponent;
  AOperation: TOperation);
begin
  inherited;
  if (AOperation = opRemove) and (AComponent = FMoveUp) then
    FMoveUp := nil;

  if (AOperation = opRemove) and (AComponent = FMoveDown) then
    FMoveDown := nil;

  if (AOperation = opRemove) and (AComponent = FList) then
    FList := nil;
end;

procedure TTIWListOrganizer.Loaded;
begin
  inherited;
 if not (csDesigning in ComponentState) then
  begin
    MakeScript;
  end;
end;

procedure TTIWListOrganizer.MakeScript;
var
  i,indexOnClick: integer;
begin
  {MoveUp}
  if Assigned(FMoveUp) then
  begin
    indexOnClick := 0;
    if (FMoveUp.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveUp.ScriptEvents.Count -1 do
      begin
        if (FMoveUp.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveUp.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveUp.ScriptEvents.Add('onClick');
    FMoveUp.ScriptEvents.HookEvent('onClick',HTMLName+'MoveUp()');
  end;

  {MoveDown}
  if Assigned(FMoveDown) then
  begin
    indexOnClick := 0;
    if (FMoveDown.ScriptEvents.Count > 0) then
    begin
      for i :=0 to FMoveDown.ScriptEvents.Count -1 do
      begin
        if (FMoveDown.ScriptEvents.Items[i].GetNamePath = 'onClick') then
          indexOnClick := i;
      end;
      FMoveDown.ScriptEvents.Delete(indexOnClick);
    end;
    FMoveDown.ScriptEvents.Add('onClick');
    FMoveDown.ScriptEvents.HookEvent('onClick',HTMLName+'MoveDown()');
  end;

end;


{$IFDEF TMSIW6}
function TTIWListOrganizer.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
{$ELSE}
function TTIWListOrganizer.RenderHTML: TIWHTMLTag;
{$ENDIF}
var
 LJScript: TStrings;
begin
  LJScript := TStringList.Create;
  try
    with LJScript do begin
      {send the content back to the server}
      Add('function '+ HTMLName + 'BuildList() {');
      Add('lbF = document.getElementById("'+FList.HTMLName+'");');
      Add('sf = "";');
      Add('for(i=0;i<lbF.options.length;i++){');
      Add(' if (i>0) ');
      Add('  sf = sf + "|"');
      if (FList.ItemsHaveValues) then
        Add('  sf = sf + lbF.options[i].text + "=" + lbF.options[i].value;')
      else
        Add('  sf = sf + lbF.options[i].text;');
      Add('}');
      Add('FindElem("'+HTMLName+'").value = sf;');
      Add('}');

   		Add('function '+ HTMLName +'MoveUp() ');
			Add('{');
			Add('	if (document.getElementById("'+FList.HTMLName+'").selectedIndex > 0)');
			Add('	{');
			Add('		var mysel = document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex].text;');
//			Add('		var myindex = document.getElementById("'+FList.HTMLName+'").selectedIndex;');
 			Add('		var myindex = document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex].value;');

			Add('');
			Add('		var myselup = document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex-1].text;');
			Add('		var myindexup = document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex-1].value;');
//			Add('		var myindexup = document.getElementById("'+FList.HTMLName+'").selectedIndex-1;');
			Add('');
			Add('		document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex].value = myindexup');
			Add('		document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex].text = myselup;');
			Add('');
			Add('		document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex-1].value = myindex;');
			Add('		document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex-1].text = mysel;');
			Add('');
			Add('		document.getElementById("'+FList.HTMLName+'").selectedIndex = document.getElementById("'+FList.HTMLName+'").selectedIndex-1;');
			Add('');
			Add('  '+HTMLName+'BuildList(); ');
			Add('	}');
			Add('}');

			Add('function '+ HTMLName +'MoveDown()');
			Add('	{');
			Add('	  if ((document.getElementById("'+FList.HTMLName+'").selectedIndex >= 0) && (document.getElementById("'+FList.HTMLName+'").selectedIndex < document.getElementById("'+FList.HTMLName+'").options.length-1) )');
			Add('	  {');
			Add('');
			Add('		var mysel = document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex].text;');
			//Add('		var myindex = document.getElementById("'+FList.HTMLName+'").selectedIndex;');
			Add('		var myindex = document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex].value;');
			Add('');
			Add('		var myseldn = document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex+1].text;');
			//Add('		var myindexdn = document.getElementById("'+FList.HTMLName+'").selectedIndex+1;');
   		Add('		var myindexdn = document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex+1].value;');
			Add('');
			Add('		document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex].value = myindexdn;');
			Add('		document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex].text = myseldn;');
			Add('');
			Add('		document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex+1].value = myindex;');
			Add('		document.getElementById("'+FList.HTMLName+'").options[document.getElementById("'+FList.HTMLName+'").selectedIndex+1].text = mysel;');
			Add('');
			Add('		document.getElementById("'+FList.HTMLName+'").selectedIndex = document.getElementById("'+FList.HTMLName+'").selectedIndex+1;');
			Add('');
			Add('  '+HTMLName+'BuildList(); ');
			Add('	  }');
			Add('	}');

    end;
    {$IFDEF TMSIW6}
    TIWComponent40Context(AContext).AddToJavaScriptOnce(LJScript.Text);
    {$ELSE}
    AddToJavaScriptOnce(LJScript.Text);
    {$ENDIF}
  finally
    FreeAndNil(LJSCript);
  end;

  Result := TIWHTMLTag.CreateTag('DIV');

  with Result.Contents.AddTag('INPUT') do
  begin
    AddStringParam('TYPE','hidden');
    AddStringParam('NAME',HTMLName);
    AddStringParam('ID',HTMLName+'_INPUT');
  end;

end;

procedure TTIWListOrganizer.SetList(alist: TIWListBox);
begin
  FList := alist;
end;

procedure TTIWListOrganizer.SetMoveDown(AButton: TIWButton);
begin
  FMoveDown := AButton;
end;

procedure TTIWListOrganizer.SetMoveUp(AButton: TIWButton);
begin
  FMoveUp := AButton;
end;

procedure TTIWListOrganizer.SetValue(const AValue: string);
var
  sl:tstringlist;
  s:string;
begin
  if (Length(AValue) = 0) then
    Exit;

  if not Assigned(FList) then
    Exit;

  sl := TStringlist.Create;

  s := AValue;

  while (pos('|',s) > 0) do
  begin
    sl.Add(copy(s,1,pos('|',s) - 1));
    delete(s,1,pos('|',s));
  end;
  if length(s) > 0 then
    sl.Add(s);

  FList.Items.Assign(sl);
  sl.Clear;

  FList.ItemIndex := 0;

  sl.Free;
end;

end.
