[PLUGIN] Listview + 11 THEME + Sorting ** Update V1.5 **

  • :D no problem , here is a capx exemple : https://www.dropbox.com/s/lp2m8wtbt6yzjjs/exemple.capx?dl=0

    ^

    Thank you very much It works just fine now. Thank you for the support and the very cool plugins!

  • Is possible to set the view to the last row when adding row? For example, when I add several rows the view of the list keeps in the same place and you need to scroll down to view the new rows, is it possible to always get the last row in view? Thanks in advance.

  • Is it possible to save the whole listview? tried with Save/Load but doesn't work

  • leotaglia , give until tonight and i will add that feature in the plugin

    Kraudi nop , but you can save the rows data and load them later

  • leotaglia , give until tonight and i will add that feature in the plugin

    Kraudi nop , but you can save the rows data and load them later

    Great, thanks! I'll wait for the update.

  • leotaglia hope tonight i can upload it

  • Hi there, is there a way to add a row containing data from 3 txtboxes?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Is possible to set the view to the last row when adding row? For example, when I add several rows the view of the list keeps in the same place and you need to scroll down to view the new rows, is it possible to always get the last row in view? Thanks in advance.

    Hi, did you have the chance to add this feature? Thanks in advance.

  • [quote:2ou4nmw0]

      Add Scroll-Top and Scroll-Bottom.

      Adjusted the "Fixed Header".

      edittime

      function GetPluginSettings() 
      {
      	return {
      		"name":		"Listview",
      		"id":			"Listview",
      		"version":		"1.3.2",
      		"description":	"Listview.",
      		"author":		"HMMG",
      		"help url":		"https://www.scirra.com/forum/plugin-listview-header-sorting_t124360",
      		"category":	"Addon",
      		"type":		"world",			// appears in layout
      		"rotatable":	false,
      		"flags":		pf_position_aces | pf_size_aces,
      		"dependency":"jquery.stickytableheaders.min.js;jquery.tablesorter.js;"+
      						"theme.black-ice.css;"+
      						"theme.blue.css;"+
      						"theme.bootstrap.css;"+
      						"theme.bootstrap_2.css;"+
      						"theme.dark.css;"+
      						"theme.default.css;"+
      						"theme.dropbox.css;"+
      						"theme.green.css;"+
      						"theme.grey.css;"+
      						"theme.ice.css;"+
      						"theme.jui.css;"
      	};
      };
      
      ////////////////////////////////////////
      // Parameter types:
      // AddNumberParam(label, description [, initial_string = "0"])			// a number
      // AddStringParam(label, description [, initial_string = "\"\""])		// a string
      // AddAnyTypeParam(label, description [, initial_string = "0"])			// accepts either a number or string
      // AddCmpParam(label, description)										// combo with equal, not equal, less, etc.
      // AddComboParamOption(text)											// (repeat before "AddComboParam" to add combo items)
      // AddComboParam(label, description [, initial_selection = 0])			// a dropdown list parameter
      // AddObjectParam(label, description)									// a button to click and pick an object type
      // AddLayerParam(label, description)									// accepts either a layer number or name (string)
      // AddLayoutParam(label, description)									// a dropdown list with all project layouts
      // AddKeybParam(label, description)										// a button to click and press a key (returns a VK)
      // AddAnimationParam(label, description)								// a string intended to specify an animation name
      // AddAudioFileParam(label, description)								// a dropdown list with all imported project audio files
      
      ////////////////////////////////////////
      // Conditions
      
      // AddCondition(id,					// any positive integer to uniquely identify this condition
      //				flags,				// (see docs) cf_none, cf_trigger, cf_fake_trigger, cf_static, cf_not_invertible,
      //									// cf_deprecated, cf_incompatible_with_triggers, cf_looping
      //				list_name,			// appears in event wizard list
      //				category,			// category in event wizard list
      //				display_str,		// as appears in event sheet - use {0}, {1} for parameters and also <b></b>, <i></i>
      //				description,		// appears in event wizard dialog when selected
      //				script_name);		// corresponding runtime function name
      				
      
      AddCondition(0, cf_trigger, "On selection changed", "Listview", "On selection changed", "Triggered when the selected ligne changes.", "OnSelectionChanged");
      AddCondition(1, cf_trigger, "On clicked", "Listview", "On clicked", "Triggered when the Listview is clicked.", "OnClicked");
      AddCondition(2, cf_trigger, "On double-clicked", "Listview", "On double-clicked", "Triggered when the Listview is double-clicked.", "OnDoubleClicked");
      AddCondition(3, cf_trigger, "On mouse over", "Listview", "On mouse over", "Triggered when the cursor is over the Listview .", "OnHover");
      
      ////////////////////////////////////////
      // Actions
      
      // AddAction(id,				// any positive integer to uniquely identify this action
      //			 flags,				// (see docs) af_none, af_deprecated
      //			 list_name,			// appears in event wizard list
      //			 category,			// category in event wizard list
      //			 display_str,		// as appears in event sheet - use {0}, {1} for parameters and also <b></b>, <i></i>
      //			 description,		// appears in event wizard dialog when selected
      //			 script_name);		// corresponding runtime function name
      
      AddNumberParam("Index", "The zero-based index of the Row to select.");
      AddAction(0, af_none, "Set selected index", "Row", "Select Row <i>{0}</i>", "Select a Row in the listview.", "SelectedRow");
      
      AddComboParamOption("Invisible");
      AddComboParamOption("Visible");
      AddComboParam("Visibility", "Choose whether to hide or show the listview.");
      AddAction(1, af_none, "Set visible", "Appearance", "Set <b>{0}</b>", "Hide or show the listview.", "SetVisible");
      
      AddAction(2, af_none, "Set focused", "Listview", "Set focused", "Set the input focus to the listview.", "SetFocus");
      AddAction(3, af_none, "Set unfocused", "Listview", "Set unfocused", "Remove the input focus from the listview.", "SetBlur");
      
      AddStringParam("Text", "The Row text to add (to add \":\" use \\:). Exemple 3 Column       \"Item1:Item2:Item3\"");
      AddAction(4, af_none, "Add Row", "Row", "Add Row <i>{0}</i>", "Append a new Row to the listview.", "AddRow");
      
      AddNumberParam("Index", "The zero-based index of the Row to insert before.");
      AddStringParam("Text", "The Row text to add (to add \":\" use \\:). Exemple 3 Column       \"Item1:Item2:Item3\"");
      AddAction(5, af_none, "Add Row at", "Row", "Add Row <i>{1}</i> at index <i>{0}</i>", "Append a new Row to a specific place in the listview.", "AddRowAt");
      
      AddNumberParam("Index", "The zero-based index of the Row to remove.");
      AddAction(6, af_none, "Remove At", "Row", "Remove Row <i>{0}</i>", "Remove a Row from the listview.", "RemoveAt");
      
      AddAction(7, af_none, "Clear", "Row", "Clear all Rows", "Remove all Rows from the listview.", "Clear");
      
      AddNumberParam("Index", "The zero-based index of the Row to Change css.");
      AddStringParam("Css", "Css exemple    \"background-color:blue;color:white;\" .");
      AddAction(8, af_none, "Change Row CSS At", "Row", "Change Row <i>{0}</i> CSS to <i>{1}</i>", "Change a Row css.", "ChangeRowCssAt");
      
      AddNumberParam("Row Index", "The zero-based index of the Row to Change the css.");
      AddNumberParam("Cell Index", "The zero-based index of the Cell to Change the css.");
      AddStringParam("Css", "Css exemple    \"background-color:blue;color:white;\" .");
      AddAction(9, af_none, "Change Cell CSS At Row", "Row", "Change Cell <i>{1}</i> At Row <i>{0}</i> CSS to <i>{2}</i>", "Change a Cell css.", "ChangeCellCssAt");
      
      AddNumberParam("Index", "The zero-based index of the Row to Change add a value to.");
      AddStringParam("Key", "Key name where to store the value in the row");
      AddStringParam("Value", "Value to store.");
      AddAction(10, af_none, "Add Value at Row", "Row", "Set <i>{1}</i> = <i>{2}</i> At <i>{0}</i>", "Store a value.", "StoreValueAt");
      
      AddNumberParam("Index", "The zero-based index of the Column to sort by.");
      AddComboParamOption("Ascendant");
      AddComboParamOption("Descendant");
      AddComboParam("Direction", "Select if the sort is Ascendant or Descendant")
      AddAction(11, af_none, "Sort Column", "Sort", "Sort Column of index <i>{0}</i> , Order <i>{1}</i> ", "Sort Column", "sortColumn");
      
      AddAction(12, af_none, "Scroll Top", "Listview", "Scroll top", "Scroll to the top line of this object.", "ScrollTop");
      AddAction(13, af_none, "Scroll bottom", "Listview", "Scroll bottom", "Scroll to the bottom of this object.", "ScrollBottom");
      
      //////////////////////////////////////// 
      // Expressions
      
      // AddExpression(id,			// any positive integer to uniquely identify this expression
      //				 flags,			// (see docs) ef_none, ef_deprecated, ef_return_number, ef_return_string,
      //								// ef_return_any, ef_variadic_parameters (one return flag must be specified)
      //				 list_name,		// currently ignored, but set as if appeared in event wizard
      //				 category,		// category in expressions panel
      //				 exp_name,		// the expression name after the dot, e.g. "foo" for "myobject.foo" - also the runtime function name
      //				 description);	// description in expressions panel
      
      AddExpression(0, ef_return_number, "", "Listview", "RowsCount", "The number of Rows in the listview.");
      AddExpression(1, ef_return_number, "", "Listview", "SelectedRowIndex", "The zero-based index of the currently selected Row.");
      
      AddNumberParam("SubTextIndex", "subText index to get.");
      AddExpression(2, ef_return_string, "", "Listview", "SubTextSelectedRow", "The subText of the currently selected Row.");
      
      AddNumberParam("RowIndex", "Row number to get.");
      AddNumberParam("SubTextIndex", "subText index to get.");
      AddExpression(3, ef_return_string, "", "Listview", "SubTextAt", "The subText of the Nth Row in the listview.");
      
      AddNumberParam("RowIndex", "Row number to get.");
      AddStringParam("Key", "Key name.");
      AddExpression(4, ef_return_string, "", "Listview", "getValueOfKeyAt", "Get stored value of key at a specific row.");
      
      ACESDone();
      
      // Property grid properties for this plugin
      var property_list = [
      	new cr.Property(ept_text,	"Header",				"",			"The initial listiew's header separeted by colon : Exemple header1:header2:header3"),
      	new cr.Property(ept_text,	"Items",				"",			"The initial listiew of items, separated by semicolons ; and colomuns separeted by colon : .Exemple Row1Col1:Row1Col2:Row1Col3;Row2Col1:Row2Col2:Row2Col3;"),
      	new cr.Property(ept_text,	"Colomun Width",	"",			"Set Listview Colomun Width separated by semicolons ;  .Exemple 20%:50%:30%"),
      	new cr.Property(ept_combo,	"Initial visibility",	"Visible",	"Choose whether the list is visible on startup.", "Invisible|Visible"),
      	new cr.Property(ept_text,	"ID (optional)",		"",			"An ID for the control allowing it to be styled with CSS from the page HTML."),
      	new cr.Property(ept_text,	"Header CSS (optional)",		"",		"Add Some CSS to your Listview's header."),
      	new cr.Property(ept_text,	"Rows CSS (optional)",		"",			"Add Some CSS to your Listview's Rows."),
      	new cr.Property(ept_text,	"Cell CSS (optional)",		"",			"Add Some CSS to your Listview's Cells."),
      	new cr.Property(ept_combo,	"Horizontal Alignement",	"Center",		"Set Columns Alignement.", "Left|Center|Right"),
      	new cr.Property(ept_combo,	"Vertical Alignement",	"Center",		"Set Columns Alignement.", "Top|Center|Bottom"),
      	new cr.Property(ept_combo,	"Show Grid",	"No",		"For listview Grid.", "No|Yes"),
      	new cr.Property(ept_combo,	"Show Sorter",	"Yes",		"Show Sorter Icons.", "No|Yes"),
      	new cr.Property(ept_combo,	"Sorter Alignement",	"Right",		"Sorter Alignement .", "Left|Center|Right"),
      	new cr.Property(ept_combo,	"Fixed Header",	"No",		"Header Fixed when scroll.", "No|Yes"),
      	new cr.Property(ept_combo,	"Allow Sort",	"No",		"Allow Sorting.", "No|Yes"),
      	new cr.Property(ept_combo,	"Theme",	"Default",		"Select Listview Theme.", "None|Black-Ice|Blue|Bootstrap|Bootstrap 2|Dark|Default|Dropbox|Green|Grey|Ice|Jui"),
      	new cr.Property(ept_combo,	"Show Y-Scroll",	"Auto",		"Show Y-Scroll.", "Auto|Yes|No")
      ];
      	
      // Called by IDE when a new object type is to be created
      function CreateIDEObjectType()
      {
      	return new IDEObjectType();
      }
      
      // Class representing an object type in the IDE
      function IDEObjectType()
      {
      	assert2(this instanceof arguments.callee, "Constructor called as a function");
      }
      
      // Called by IDE when a new object instance of this type is to be created
      IDEObjectType.prototype.CreateInstance = function(instance)
      {
      	return new IDEInstance(instance);
      }
      
      // Class representing an individual instance of an object in the IDE
      function IDEInstance(instance, type)
      {
      	assert2(this instanceof arguments.callee, "Constructor called as a function");
      	
      	// Save the constructor parameters
      	this.instance = instance;
      	this.type = type;
      	
      	// Set the default property values from the property table
      	this.properties = {};
      	
      	for (var i = 0; i < property_list.length; i++)
      		this.properties[property_list[i].name] = property_list[i].initial_value;
      		
      	// Plugin-specific variables
      	this.just_inserted = false;
      	this.font = null;
      }
      
      IDEInstance.prototype.OnCreate = function()
      {
      	this.instance.SetHotspot(new cr.vector2(0, 0));
      }
      
      IDEInstance.prototype.OnInserted = function()
      {
      	this.instance.SetSize(new cr.vector2(150, 22));
      }
      
      IDEInstance.prototype.OnDoubleClicked = function()
      {
      }
      
      // Called by the IDE after a property has been changed
      IDEInstance.prototype.OnPropertyChanged = function(property_name)
      {
      }
      
      IDEInstance.prototype.OnRendererInit = function(renderer)
      {
      }
      	
      // Called to draw self in the editor
      IDEInstance.prototype.Draw = function(renderer)
      {
      	if (!this.font)
      		this.font = renderer.CreateFont("Arial", 14, false, false);
      		
      	renderer.SetTexture(null);
      	var quad = this.instance.GetBoundingQuad();
      	renderer.Fill(quad, this.properties["Enabled"] === "Yes" ? cr.RGB(255, 255, 255) : cr.RGB(224, 224, 224));
      	renderer.Outline(quad, cr.RGB(0, 0, 0));
      	
      	cr.quad.prototype.offset.call(quad, 4, 2);
      	
      	this.font.DrawText(this.properties["Items"].replace(/;/g, "\n"),
      							quad,
      							cr.RGB(0, 0, 0),
      							ha_left);
      
      }
      
      IDEInstance.prototype.OnRendererReleased = function(renderer)
      {
      	this.font = null;
      }
      [/code:2ou4nmw0]
      
      [b]runtime[/b]
      [code:2ou4nmw0]
      // ECMAScript 5 strict mode
      "use strict";
      // Dropbox , Grey , Bootstap Theme dont have Sort icons
      assert2(cr, "cr namespace not created");
      assert2(cr.plugins_, "cr.plugins_ not created");
      
      /////////////////////////////////////
      // Plugin class
      cr.plugins_.Listview = function(runtime)
      {
      	this.runtime = runtime;
      };
      
      (function ()
      {
      	/////////////////////////////////////
      	var pluginProto = cr.plugins_.Listview.prototype;
      		
      	/////////////////////////////////////
      	// Object type class
      	pluginProto.Type = function(plugin)
      	{
      		this.plugin = plugin;
      		this.runtime = plugin.runtime;
      	};
      
      	var typeProto = pluginProto.Type.prototype;
      
      	// called on startup for each object type
      	typeProto.onCreate = function()
      	{
      	};
      
      	/////////////////////////////////////
      	// Instance class
      	pluginProto.Instance = function(type)
      	{
      		this.type = type;
      		this.runtime = type.runtime;
      	};
      	
      	var instanceProto = pluginProto.Instance.prototype;
      	
      	// called whenever an instance is created
      	instanceProto.onCreate = function()
      	{
      		// Not supported in DC
      		if (this.runtime.isDomFree)
      		{
      			cr.logexport("[Construct 2] List plugin not supported on this platform - the object will not be created");
      			return;
      		}
      	
      		this.elem = document.createElement("div");
      		this.elem.table = document.createElement("table");
      		this.elem.id = this.properties[4];
      		if($.trim(this.elem.id) <= 0)
      		{
      			this.elem.id = makeid();
      		}
      		this.lastSelection = -1 ;
      
      		$(this.elem).appendTo(this.runtime.canvasdiv ? this.runtime.canvasdiv : "body");
      		
      		if(this.properties[16] == 0)
      			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","auto").css("padding","0px").css("margin","0px");
      		else if(this.properties[16] == 1)
      			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","scroll").css("padding","0px").css("margin","0px");
      		else if(this.properties[16] == 2)
      			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","hidden").css("padding","0px").css("margin","0px");
      		
      		var self = this;
      		var header = [];
      		var ligne = [];
      		var lenCol = [];
      		var align = "";
      		var valign = "";
      		var theme = "";
      		
      		if($.trim(self.properties[0]).length>0)
      		{
      			if(self.properties[0][self.properties[0].length-1] == ":")
      				self.properties[0]= self.properties[0].slice(0,-1);
      			header=self.properties[0].split(":");
      		}
      		
      		if($.trim(self.properties[1]).length>0)
      		{
      			if(self.properties[1][self.properties[1].length-1] == ";")
      				self.properties[1]= self.properties[1].slice(0,-1);
      			ligne=self.properties[1].split(";");
      		}
      		
      		if($.trim(self.properties[2]).length>0)
      		{
      			if(self.properties[2][self.properties[2].length-1] == ":")
      				self.properties[2]= self.properties[2].slice(0,-1);
      			lenCol=self.properties[2].split(":");
      		}
      		
      		switch(self.properties[8])
      		{
      			case 0 : align="left";break;
      			case 1 : align="center";break;
      			case 2 : align="right";break;
      			default : align="center";break;
      		}
      		switch(self.properties[9])
      		{
      			case 0 : valign="top";break;
      			case 1 : valign="center";break;
      			case 2 : valign="bottom";break;
      			default : valign="center";break;
      		}
      		
      		
      		this.align = align;
      		this.valign = valign;
      		//$(self.elem.table).addClass("tablesorter");
      		
      		
      		$(self.elem.table).attr({
      							"border":self.properties[10],
      							"cellpadding":"0px",
      							"cellspacing":"0px",
      							"width":"100%"
      		}).css("color","black");
      
      		if(header.length>0)
      		{	
      			$(self.elem.table).append("<thead><tr></tr></thead>");
      			for(var i=0 ; i<header.length ; i++)
      			{
      				$(this.elem.table).find("thead tr").append("<th width='"+lenCol[i]+"' colNum='"+i+"' align='"+align+"' valign='"+valign+"' >"+header[i]+"</th>");
      			}
      		}
      		
      
      		$(self.elem.table).append("<tbody></tbody>");
      		if(ligne.length>0)
      		{
      			for(var i=0 ; i<ligne.length ; i++)
      			{
      				var rowId = "";
      				do
      				{
      					rowId = makeid();
      				}while( $("#"+rowId).length);
      				var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
      				var a = ligne[i].split(":");
      				for(var j=0 ; j<a.length ; j++)
      				{
      					if($.trim(self.properties[7]).length >0)
      						LigneToAdd.append("<td align='"+align+"' valign='"+valign+"' style='"+self.properties[7]+"'>"+a[j]+"</td>");
      					else
      						LigneToAdd.append("<td align='"+align+"' valign='"+valign+"'>"+a[j]+"</td>");
      				}
      				$(self.elem.table).find("tbody").append(LigneToAdd);
      			}
      		}
      
      		if($.trim(self.properties[5]).length >0)
      			$(self.elem.table).find("thead tr").attr("style",self.properties[5]);
      		if($.trim(self.properties[6]).length >0)
      			$(self.elem.table).find("tbody tr").attr("style",self.properties[6]);
      		
      		if( self.properties[14] == 1)
      		{
      			if(self.properties[15] > 0)
      			{
      				switch(self.properties[15])
      				{
      					case 0 : theme="none";break;
      					case 1 : theme="blackice";break;
      					case 2 : theme="blue";break;
      					case 3 : theme="bootstrap";break;
      					case 4 : theme="bootstrap_2";break;
      					case 5 : theme="dark";break;
      					case 6 : theme="default";break;
      					case 7 : theme="dropbox";break;
      					case 8 : theme="green";break;
      					case 9 : theme="grey";break;
      					case 10 : theme="ice";break;
      					case 11 : theme="jui";break;
      					default : theme="default";break;
      				}
      				$(self.elem.table).tablesorter(
      				{
      					theme:theme
      				});
      			}
      			else
      			{
      				$(self.elem.table).tablesorter().removeClass("tablesorter-default");
      			}
      		}
      		else
      		{
      			if(self.properties[15] > 0)
      			{
      				switch(self.properties[15])
      				{
      					case 0 : theme="none";break;
      					case 1 : theme="blackice";break;
      					case 2 : theme="blue";break;
      					case 3 : theme="bootstrap";break;
      					case 4 : theme="bootstrap_2";break;
      					case 5 : theme="dark";break;
      					case 6 : theme="default";break;
      					case 7 : theme="dropbox";break;
      					case 8 : theme="green";break;
      					case 9 : theme="grey";break;
      					case 10 : theme="ice";break;
      					case 11 : theme="jui";break;
      					default : theme="default";break;
      				}
      				$(self.elem.table).addClass("tablesorter-"+theme);
      			}
      		}
      
      		if( self.properties[13] == 1)
      			$(self.elem.table).stickyTableHeaders({ scrollableArea: $(".scrollable-area-"+this.elem.id) })
      
      		var sorterAlign = 2;
      		var sorterVisib = "initial";
      
      		switch(self.properties[12])
      		{
      			case 0 : sorterAlign="left";break;
      			case 1 : sorterAlign="center";break;
      			case 2 : sorterAlign="right";break;
      			default : sorterVisib="right";break;
      		}
      
      				
      		$(self.elem.table).find("thead tr .header").css(
      		{
      			"background-position":"center "+sorterAlign
      		});	
      		if( self.properties[11] == 0)
      		{
      			$(self.elem.table).find("thead tr .header").css(
      			{
      				"background-image":"none"
      			});
      		}
      		
      		
      		$(this.elem.table).find("tbody").on('click' , 'tr', function() 
      		{
      			if( parseInt($(this).index()) != self.lastSelection)
      			{
      				self.lastSelection = parseInt($(this).index());
      				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnSelectionChanged, self);
      			}
      		});
      		
      		$(this.elem.table).find("tbody").on('mouseover' , 'tr', function() 
      		{
      			self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnHover, self);
      		});
      		
      		this.elem.onclick = function(e) {
      				e.stopPropagation();
      				self.runtime.isInUserInputEvent = true;
      				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnClicked, self);
      				self.runtime.isInUserInputEvent = false;
      			};
      		
      		this.elem.ondblclick = function(e) {
      				e.stopPropagation();
      				self.runtime.isInUserInputEvent = true;
      				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnDoubleClicked, self);
      				self.runtime.isInUserInputEvent = false;
      			};
      		
      		// Prevent touches reaching the canvas
      		this.elem.addEventListener("touchstart", function (e) {
      			e.stopPropagation();
      		}, false);
      		
      		this.elem.addEventListener("touchmove", function (e) {
      			e.stopPropagation();
      		}, false);
      		
      		this.elem.addEventListener("touchend", function (e) {
      			e.stopPropagation();
      		}, false);
      		
      		// Prevent clicks being blocked
      		jQuery(this.elem).mousedown(function (e) {
      			e.stopPropagation();
      		});
      		
      		jQuery(this.elem).mouseup(function (e) {
      			e.stopPropagation();
      		});
      		
      		this.lastLeft = 0;
      		this.lastTop = 0;
      		this.lastRight = 0;
      		this.lastBottom = 0;
      		this.lastWinWidth = 0;
      		this.lastWinHeight = 0;
      		this.isVisible = true;
      		
      		this.updatePosition(true);
      		
      		this.runtime.tickMe(this);
      	};
      	
      	instanceProto.saveToJSON = function ()
      	{
      		var o = {
      			"tooltip": this.elem.title,
      			"disabled": !!this.elem.disabled,
      			"items": [],
      			"sel": []
      		};
      		
      		var i, len;
      		var itemsarr = o["items"];
      		
      		for (i = 0, len = this.elem.length; i < len; i++)
      		{
      			itemsarr.push(this.elem.options[i].text);
      		}
      		
      		var selarr = o["sel"];
      		
      		if (this.elem["multiple"])
      		{
      			for (i = 0, len = this.elem.length; i < len; i++)
      			{
      				if (this.elem.options[i].selected)
      					selarr.push(i);
      			}
      		}
      		else
      		{
      			selarr.push(this.elem["selectedIndex"]);
      		}
      		
      		return o;
      	};
      	
      	instanceProto.loadFromJSON = function (o)
      	{
      		this.elem.title = o["tooltip"];
      		this.elem.disabled = o["disabled"];
      		
      		var itemsarr = o["items"];
      		
      		// Clear the list
      		while (this.elem.length)
      			this.elem.remove(this.elem.length - 1);
      			
      		var i, len, opt;
      		for (i = 0, len = itemsarr.length; i < len; i++)
      		{
      			opt = document.createElement("option");
      			opt.text = itemsarr[i];
      			this.elem.add(opt);
      		}
      		
      		var selarr = o["sel"];
      		
      		if (this.elem["multiple"])
      		{
      			for (i = 0, len = selarr.length; i < len; i++)
      			{
      				if (selarr[i] < this.elem.length)
      					this.elem.options[selarr[i]].selected = true;
      			}
      		}
      		else if (selarr.length >= 1)
      		{
      			this.elem["selectedIndex"] = selarr[0];
      		}
      	};
      	
      	instanceProto.onDestroy = function ()
      	{
      		if (this.runtime.isDomFree)
      				return;
      		
      		jQuery(this.elem).remove();
      		this.elem = null;
      	};
      	
      	instanceProto.tick = function ()
      	{
      		this.updatePosition();
      	};
      	
      	instanceProto.updatePosition = function (first)
      	{
      		if (this.runtime.isDomFree)
      			return;
      		
      		var left = this.layer.layerToCanvas(this.x, this.y, true);
      		var top = this.layer.layerToCanvas(this.x, this.y, false);
      		var right = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, true);
      		var bottom = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, false);
      		
      		var rightEdge = this.runtime.width / this.runtime.devicePixelRatio;
      		var bottomEdge = this.runtime.height / this.runtime.devicePixelRatio;
      		
      		// Is entirely offscreen or invisible: hide
      		if (!this.visible || !this.layer.visible || right <= 0 || bottom <= 0 || left >= rightEdge || top >= bottomEdge)
      		{
      			if (this.isVisible)
      				jQuery(this.elem).hide();
      			
      			this.isVisible = false;
      			return;
      		}
      		
      		// Truncate to canvas size
      		if (left < 1)
      			left = 1;
      		if (top < 1)
      			top = 1;
      		if (right >= rightEdge)
      			right = rightEdge - 1;
      		if (bottom >= bottomEdge)
      			bottom = bottomEdge - 1;
      		
      		var curWinWidth = window.innerWidth;
      		var curWinHeight = window.innerHeight;
      			
      		// Avoid redundant updates
      		if (!first && this.lastLeft === left && this.lastTop === top && this.lastRight === right && this.lastBottom === bottom && this.lastWinWidth === curWinWidth && this.lastWinHeight === curWinHeight)
      		{
      			if (!this.isVisible)
      			{
      				jQuery(this.elem).show();
      				this.isVisible = true;
      			}
      			
      			return;
      		}
      			
      		this.lastLeft = left;
      		this.lastTop = top;
      		this.lastRight = right;
      		this.lastBottom = bottom;
      		this.lastWinWidth = curWinWidth;
      		this.lastWinHeight = curWinHeight;
      		
      		if (!this.isVisible)
      		{
      			jQuery(this.elem).show();
      			this.isVisible = true;
      		}
      		
      		var offx = Math.round(left) + jQuery(this.runtime.canvas).offset().left;
      		var offy = Math.round(top) + jQuery(this.runtime.canvas).offset().top;
      		jQuery(this.elem).css("position", "absolute");
      		jQuery(this.elem).offset({left: offx, top: offy});
      		jQuery(this.elem).width(Math.round(right - left));
      		jQuery(this.elem).height(Math.round(bottom - top));
      		
      	};
      	
      	// only called if a layout object
      	instanceProto.draw = function(ctx)
      	{
      	};
      	
      	instanceProto.drawGL = function(glw)
      	{
      	};
      	
      	/**BEGIN-PREVIEWONLY**/
      	instanceProto.getDebuggerValues = function (propsections)
      	{
      		propsections.push({
      			"title": "List",
      			"properties": [
      				{"name": "Item count", "value": this.elem.length, "readonly": true},
      				{"name": "Enabled", "value": !this.elem.disabled},
      				{"name": "Tooltip", "value": this.elem.title},
      				{"name": "Selected index", "value": this.elem.selectedIndex}
      			]
      		});
      		
      		var props = [], i, len;
      		for (i = 0, len = this.elem.length; i < len; ++i)
      		{
      			props.push({"name": i.toString(), "value": this.elem.options[i].text});
      		}
      		
      		propsections.push({
      			"title": "Items",
      			"properties": props
      		});
      	};
      	
      	instanceProto.onDebugValueEdited = function (header, name, value)
      	{
      		if (header === "List")
      		{
      			switch (name) {
      			case "Enabled":
      				this.elem.disabled = !value;
      				break;
      			case "Tooltip":
      				this.elem.title = value;
      				break;
      			case "Selected index":
      				this.elem.selectedIndex = value;
      				break;
      			}
      		}
      		else if (header === "Items")
      		{
      			this.elem.options[parseInt(name, 10)].text = value;
      		}
      	};
      	/**END-PREVIEWONLY**/
      
      	//////////////////////////////////////
      	// Conditions
      	function Cnds() {};
      	
      	Cnds.prototype.OnSelectionChanged = function ()
      	{
      		return true;
      	};
      	
      	Cnds.prototype.OnClicked = function ()
      	{
      		return true;
      	};
      	
      	Cnds.prototype.OnDoubleClicked = function ()
      	{
      		return true;
      	};
      	
      	Cnds.prototype.OnHover = function ()
      	{
      		return true;
      	};
      	
      	
      	pluginProto.cnds = new Cnds();
      	
      	//////////////////////////////////////
      	// Actions
      	function Acts() {};
      	
      	Acts.prototype.SelectedRow = function (i)
      	{
      		if (this.runtime.isDomFree)
      			return;
      		
      		this.lastSelection = i;
      		$(this.elem.table).find("tbody tr.selected").removeClass("selected");
      		$(this.elem.table).find("tbody tr").eq(i).addClass("selected");
      	};
      	
      	Acts.prototype.SetVisible = function (vis)
      	{
      		if (this.runtime.isDomFree)
      			return;
      		
      		this.visible = (vis !== 0);
      	};
      	
      	Acts.prototype.SetFocus = function ()
      	{
      		if (this.runtime.isDomFree)
      			return;
      		
      		this.elem.table.focus();
      	};
      	
      	Acts.prototype.SetBlur = function ()
      	{
      		if (this.runtime.isDomFree)
      			return;
      		
      		this.elem.table.blur();
      	};
      
      	
      	Acts.prototype.AddRow = function (text_)
      	{
      		if (this.runtime.isDomFree)
      			return;
      
      		var rowId = "";
      		do { rowId = makeid(); }
      		while( $("#"+rowId).length);
      		
      		
      		var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
      		var a = text_.split(":");
      		var r = a.toString().replace(/\\,/g, ":");
      		a = r.split(",");
      
      		for(var j=0 ; j<a.length ; j++)
      		{
      			LigneToAdd.append("<td align='"+this.align+"' valign='"+this.valign+"' style='"+this.properties[7]+"'>"+a[j]+"</td>");
      		}
      
      		$(this.elem.table).find("tbody").append(LigneToAdd);
      
      		if( this.properties[14] == 1)
      		{
      			$(this.elem.table).trigger('update');     
      			$(this.elem.table).trigger("sorton",[$(this.elem.table).get(0).config.sortList]); 
      		}
      	};
      	
      	Acts.prototype.AddRowAt = function (index_, text_)
      	{
      		if (this.runtime.isDomFree)
      			return;
      
      		var rowId = "";
      		do
      		{
      			rowId = makeid();
      		}while( $("#"+rowId).length);
      		
      		
      		var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
      		var a = text_.split(":");
      		var r = a.toString().replace(/,,/g, ":");
      		a = r.split(",");
      		for(var j=0 ; j<a.length ; j++)
      		{
      			LigneToAdd.append("<td align='"+this.align+"' valign='"+this.valign+"' style='"+this.properties[7]+"'>"+a[j]+"</td>");
      		}
      		
      		if(index_ > 0)
      			LigneToAdd.insertBefore($(this.elem.table).find("tbody tr").eq(index_));
      		else
      			LigneToAdd.appendTo($(this.elem.table).find("tbody"));
      		
      		if( this.properties[14] == 1 )
      		{
      			$(this.elem.table).trigger('update');
      			$(this.elem.table).trigger("sorton",[$(this.elem.table).get(0).config.sortList]); 
      		}
      	};
      	
      	Acts.prototype.RemoveAt = function (index_)
      	{
      		if (this.runtime.isDomFree)
      			return;
      		
      		if(index_ == this.lastSelection)
      				this.lastSelection = -1 ;
      
      		$(this.elem.table).find("tbody tr").eq(index_).remove();
      	};
      
      	Acts.prototype.ChangeRowCssAt = function (index_,css)
      	{
      		if (this.runtime.isDomFree)
      			return;
      		
      		var item = $(this.elem.table).find("tbody tr").eq(index_);
      		if(item.is("[style]"))
      			item.attr("style",item.attr("style")+css);
      		else
      			item.attr("style",css);
      	};
      	
      	Acts.prototype.ChangeCellCssAt = function (index_,index_2,css)
      	{
      		if (this.runtime.isDomFree)
      			return;
      
      		var item = $(this.elem.table).find("tbody tr").eq(index_).find("td").eq(index_2);
      		if(item.is("[style]"))
      			item.attr("style",item.attr("style")+css);
      		else
      			item.attr("style",css);
      	};
      	
      	Acts.prototype.StoreValueAt = function (index_,key,val)
      	{
      		if (this.runtime.isDomFree)
      			return;
      
      		$(this.elem.table).find("tbody tr").eq(index_).attr(key,val);
      	};
      	
      	Acts.prototype.sortColumn = function (index_,val)
      	{
      		if (this.runtime.isDomFree)
      			return;
      		$("table").trigger("sorton",[ [[index_,val]] ]);
      		
      	};
      	
      	Acts.prototype.Clear = function ()
      	{
      		$(this.elem.table).find("tbody tr").remove();
      	};
      
      	Acts.prototype.ScrollTop = function ()
      	{
      		if (this.runtime.isDomFree)
      			return;
      
              this.elem.scrollTop = 0;
      	};
      
      	Acts.prototype.ScrollBottom = function ()
      	{
      		if (this.runtime.isDomFree)
      			return;
      		
      		this.elem.scrollTop = this.elem.scrollHeight;
      	};
      	
      	pluginProto.acts = new Acts();
      	
      	//////////////////////////////////////
      	// Expressions
      	function Exps() {};
      	
      	Exps.prototype.RowsCount = function (ret)
      	{
      		if (this.runtime.isDomFree)
      		{
      			ret.set_int(0);
      			return;
      		}
      		
      		ret.set_int($(this.elem.table).find("tbody tr").length);
      	};
      	
      	Exps.prototype.SelectedRowIndex = function (ret)
      	{
      		if (this.runtime.isDomFree)
      		{
      			ret.set_int(0);
      			return;
      		}
      		ret.set_int(this.lastSelection);
      	};
      	
      	Exps.prototype.SubTextSelectedRow = function (ret,SubTextIndex)
      	{
      		if (this.runtime.isDomFree)
      		{
      			ret.set_string("");
      			return;
      		}
      		
      		ret.set_string($(this.elem.table).find("tbody tr").eq(this.lastSelection).find("td").eq(SubTextIndex).text());
      	};
      	
      	
      	Exps.prototype.SubTextAt = function (ret,LigneIndex , SubTextIndex)
      	{
      		if (this.runtime.isDomFree)
      		{
      			ret.set_string("");
      			return;
      		}
      		
      		ret.set_string($(this.elem.table).find("tbody tr").eq(LigneIndex).find("td").eq(SubTextIndex).text() );
      	};
      	
      	
      	Exps.prototype.getValueOfKeyAt = function (ret,RowIndex , Key)
      	{
      		if (this.runtime.isDomFree)
      		{
      			ret.set_string("");
      			return;
      		}
      		
      		ret.set_string($(this.elem.table).find("tbody tr").eq(RowIndex).attr(Key) );
      	};
      	pluginProto.exps = new Exps();
      
      }());
      
      function makeid()
      {
          var text = "";
          var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
      	
          for( var i=0; i < 10; i++ )
              text += possible.charAt(Math.floor(Math.random() * possible.length));
          return text;
      }
      
      function createCSSSelector(selector, style) 
      {
      	var cssrules =  $("<style type='text/css'> </style>").appendTo("head");
      	cssrules.append(selector+"{ "+style+" }"); 
      }
      [/code:2ou4nmw0]
    • How do i edit a cell?

    • andykenobi

      *Sorry for the delay.

      [quote:20rxu6ru]

        Add Set Header (*not stable with fixed header).

        Add Change Value.

        edittime

        function GetPluginSettings() 
        {
        	return {
        		"name":		"Listview",
        		"id":			"Listview",
        		"version":		"1.3.2",
        		"version modified":		"2",
        		"description":	"Listview.",
        		"author":		"HMMG",
        		"modified by":	"PlayLive",
        		"help url":		"https://www.scirra.com/forum/plugin-listview-header-sorting_t124360",
        		"category":	"Addon",
        		"type":		"world",			// appears in layout
        		"rotatable":	false,
        		"flags":		pf_position_aces | pf_size_aces,
        		"dependency":"jquery.stickytableheaders.min.js;jquery.tablesorter.js;"+
        						"theme.black-ice.css;"+
        						"theme.blue.css;"+
        						"theme.bootstrap.css;"+
        						"theme.bootstrap_2.css;"+
        						"theme.dark.css;"+
        						"theme.default.css;"+
        						"theme.dropbox.css;"+
        						"theme.green.css;"+
        						"theme.grey.css;"+
        						"theme.ice.css;"+
        						"theme.jui.css;"
        	};
        };
        
        ////////////////////////////////////////
        // Parameter types:
        // AddNumberParam(label, description [, initial_string = "0"])			// a number
        // AddStringParam(label, description [, initial_string = "\"\""])		// a string
        // AddAnyTypeParam(label, description [, initial_string = "0"])			// accepts either a number or string
        // AddCmpParam(label, description)										// combo with equal, not equal, less, etc.
        // AddComboParamOption(text)											// (repeat before "AddComboParam" to add combo items)
        // AddComboParam(label, description [, initial_selection = 0])			// a dropdown list parameter
        // AddObjectParam(label, description)									// a button to click and pick an object type
        // AddLayerParam(label, description)									// accepts either a layer number or name (string)
        // AddLayoutParam(label, description)									// a dropdown list with all project layouts
        // AddKeybParam(label, description)										// a button to click and press a key (returns a VK)
        // AddAnimationParam(label, description)								// a string intended to specify an animation name
        // AddAudioFileParam(label, description)								// a dropdown list with all imported project audio files
        
        ////////////////////////////////////////
        // Conditions
        
        // AddCondition(id,					// any positive integer to uniquely identify this condition
        //				flags,				// (see docs) cf_none, cf_trigger, cf_fake_trigger, cf_static, cf_not_invertible,
        //									// cf_deprecated, cf_incompatible_with_triggers, cf_looping
        //				list_name,			// appears in event wizard list
        //				category,			// category in event wizard list
        //				display_str,		// as appears in event sheet - use {0}, {1} for parameters and also <b></b>, <i></i>
        //				description,		// appears in event wizard dialog when selected
        //				script_name);		// corresponding runtime function name
        				
        
        AddCondition(0, cf_trigger, "On selection changed", "Listview", "On selection changed", "Triggered when the selected ligne changes.", "OnSelectionChanged");
        AddCondition(1, cf_trigger, "On clicked", "Listview", "On clicked", "Triggered when the Listview is clicked.", "OnClicked");
        AddCondition(2, cf_trigger, "On double-clicked", "Listview", "On double-clicked", "Triggered when the Listview is double-clicked.", "OnDoubleClicked");
        AddCondition(3, cf_trigger, "On mouse over", "Listview", "On mouse over", "Triggered when the cursor is over the Listview .", "OnHover");
        
        ////////////////////////////////////////
        // Actions
        
        // AddAction(id,				// any positive integer to uniquely identify this action
        //			 flags,				// (see docs) af_none, af_deprecated
        //			 list_name,			// appears in event wizard list
        //			 category,			// category in event wizard list
        //			 display_str,		// as appears in event sheet - use {0}, {1} for parameters and also <b></b>, <i></i>
        //			 description,		// appears in event wizard dialog when selected
        //			 script_name);		// corresponding runtime function name
        
        AddNumberParam("Index", "The zero-based index of the Row to select.");
        AddAction(0, af_none, "Set selected index", "Row", "Select Row <i>{0}</i>", "Select a Row in the listview.", "SelectedRow");
        
        AddComboParamOption("Invisible");
        AddComboParamOption("Visible");
        AddComboParam("Visibility", "Choose whether to hide or show the listview.");
        AddAction(1, af_none, "Set visible", "Appearance", "Set <b>{0}</b>", "Hide or show the listview.", "SetVisible");
        
        AddAction(2, af_none, "Set focused", "Listview", "Set focused", "Set the input focus to the listview.", "SetFocus");
        AddAction(3, af_none, "Set unfocused", "Listview", "Set unfocused", "Remove the input focus from the listview.", "SetBlur");
        
        AddStringParam("Text", "The Row text to add (to add \":\" use \\:). Exemple 3 Column       \"Item1:Item2:Item3\"");
        AddAction(4, af_none, "Add Row", "Row", "Add Row <i>{0}</i>", "Append a new Row to the listview.", "AddRow");
        
        AddNumberParam("Index", "The zero-based index of the Row to insert before.");
        AddStringParam("Text", "The Row text to add (to add \":\" use \\:). Exemple 3 Column       \"Item1:Item2:Item3\"");
        AddAction(5, af_none, "Add Row at", "Row", "Add Row <i>{1}</i> at index <i>{0}</i>", "Append a new Row to a specific place in the listview.", "AddRowAt");
        
        AddNumberParam("Index", "The zero-based index of the Row to remove.");
        AddAction(6, af_none, "Remove At", "Row", "Remove Row <i>{0}</i>", "Remove a Row from the listview.", "RemoveAt");
        
        AddAction(7, af_none, "Clear", "Row", "Clear all Rows", "Remove all Rows from the listview.", "Clear");
        
        AddNumberParam("Index", "The zero-based index of the Row to Change css.");
        AddStringParam("Css", "Css exemple    \"background-color:blue;color:white;\" .");
        AddAction(8, af_none, "Change Row CSS At", "Row", "Change Row <i>{0}</i> CSS to <i>{1}</i>", "Change a Row css.", "ChangeRowCssAt");
        
        AddNumberParam("Row Index", "The zero-based index of the Row to Change the css.");
        AddNumberParam("Cell Index", "The zero-based index of the Cell to Change the css.");
        AddStringParam("Css", "Css exemple    \"background-color:blue;color:white;\" .");
        AddAction(9, af_none, "Change Cell CSS At Row", "Row", "Change Cell <i>{1}</i> At Row <i>{0}</i> CSS to <i>{2}</i>", "Change a Cell css.", "ChangeCellCssAt");
        
        AddNumberParam("Index", "The zero-based index of the Row to Change add a value to.");
        AddStringParam("Key", "Key name where to store the value in the row");
        AddStringParam("Value", "Value to store.");
        AddAction(10, af_none, "Add Value at Row", "Row", "Set <i>{1}</i> = <i>{2}</i> At <i>{0}</i>", "Store a value.", "StoreValueAt");
        
        AddNumberParam("Index", "The zero-based index of the Column to sort by.");
        AddComboParamOption("Ascendant");
        AddComboParamOption("Descendant");
        AddComboParam("Direction", "Select if the sort is Ascendant or Descendant")
        AddAction(11, af_none, "Sort Column", "Sort", "Sort Column of index <i>{0}</i> , Order <i>{1}</i> ", "Sort Column", "sortColumn");
        
        // PlayLive
        AddAction(12, af_none, "Scroll Top", "Listview", "Scroll top", "Scroll to the top line of this object.", "ScrollTop");
        AddAction(13, af_none, "Scroll bottom", "Listview", "Scroll bottom", "Scroll to the bottom of this object.", "ScrollBottom");
        
        AddStringParam("Text", "Set Header (to add \":\" use \\:). Exemple 3 Column       \"Header1:Header2:Header3\"");
        AddAction(14, af_none, "Set Header", "Listview", "Set the header (<i>{0}</i>)", "Set the header.", "SetHeader");
        
        AddNumberParam("Row Index", "The zero-based index of the Row to change the value.");
        AddNumberParam("Cell Index", "The zero-based index of the Cell to change the value.");
        AddStringParam("Value", "Change value (to add \":\" use \\:).");
        AddAction(15, af_none, "Change Value", "Row", "Change value [{0}][{1}] to (<i>{2}</i>)", "Change value at row and cell.", "ChangeValue");
        
        //////////////////////////////////////// 
        // Expressions
        
        // AddExpression(id,			// any positive integer to uniquely identify this expression
        //				 flags,			// (see docs) ef_none, ef_deprecated, ef_return_number, ef_return_string,
        //								// ef_return_any, ef_variadic_parameters (one return flag must be specified)
        //				 list_name,		// currently ignored, but set as if appeared in event wizard
        //				 category,		// category in expressions panel
        //				 exp_name,		// the expression name after the dot, e.g. "foo" for "myobject.foo" - also the runtime function name
        //				 description);	// description in expressions panel
        
        AddExpression(0, ef_return_number, "", "Listview", "RowsCount", "The number of Rows in the listview.");
        AddExpression(1, ef_return_number, "", "Listview", "SelectedRowIndex", "The zero-based index of the currently selected Row.");
        
        AddNumberParam("SubTextIndex", "subText index to get.");
        AddExpression(2, ef_return_string, "", "Listview", "SubTextSelectedRow", "The subText of the currently selected Row.");
        
        AddNumberParam("RowIndex", "Row number to get.");
        AddNumberParam("SubTextIndex", "subText index to get.");
        AddExpression(3, ef_return_string, "", "Listview", "SubTextAt", "The subText of the Nth Row in the listview.");
        
        AddNumberParam("RowIndex", "Row number to get.");
        AddStringParam("Key", "Key name.");
        AddExpression(4, ef_return_string, "", "Listview", "getValueOfKeyAt", "Get stored value of key at a specific row.");
        
        ACESDone();
        
        // Property grid properties for this plugin
        var property_list = [
        	new cr.Property(ept_text,	"Header",				"",			"The initial listiew's header separeted by colon : Exemple header1:header2:header3"),
        	new cr.Property(ept_text,	"Items",				"",			"The initial listiew of items, separated by semicolons ; and colomuns separeted by colon : .Exemple Row1Col1:Row1Col2:Row1Col3;Row2Col1:Row2Col2:Row2Col3;"),
        	new cr.Property(ept_text,	"Colomun Width",	"",			"Set Listview Colomun Width separated by semicolons ;  .Exemple 20%:50%:30%"),
        	new cr.Property(ept_combo,	"Initial visibility",	"Visible",	"Choose whether the list is visible on startup.", "Invisible|Visible"),
        	new cr.Property(ept_text,	"ID (optional)",		"",			"An ID for the control allowing it to be styled with CSS from the page HTML."),
        	new cr.Property(ept_text,	"Header CSS (optional)",		"",		"Add Some CSS to your Listview's header."),
        	new cr.Property(ept_text,	"Rows CSS (optional)",		"",			"Add Some CSS to your Listview's Rows."),
        	new cr.Property(ept_text,	"Cell CSS (optional)",		"",			"Add Some CSS to your Listview's Cells."),
        	new cr.Property(ept_combo,	"Horizontal Alignement",	"Center",		"Set Columns Alignement.", "Left|Center|Right"),
        	new cr.Property(ept_combo,	"Vertical Alignement",	"Center",		"Set Columns Alignement.", "Top|Center|Bottom"),
        	new cr.Property(ept_combo,	"Show Grid",	"No",		"For listview Grid.", "No|Yes"),
        	new cr.Property(ept_combo,	"Show Sorter",	"Yes",		"Show Sorter Icons.", "No|Yes"),
        	new cr.Property(ept_combo,	"Sorter Alignement",	"Right",		"Sorter Alignement .", "Left|Center|Right"),
        	new cr.Property(ept_combo,	"Fixed Header",	"No",		"Header Fixed when scroll.", "No|Yes"),
        	new cr.Property(ept_combo,	"Allow Sort",	"No",		"Allow Sorting.", "No|Yes"),
        	new cr.Property(ept_combo,	"Theme",	"Default",		"Select Listview Theme.", "None|Black-Ice|Blue|Bootstrap|Bootstrap 2|Dark|Default|Dropbox|Green|Grey|Ice|Jui"),
        	new cr.Property(ept_combo,	"Show Y-Scroll",	"Auto",		"Show Y-Scroll.", "Auto|Yes|No")
        ];
        	
        // Called by IDE when a new object type is to be created
        function CreateIDEObjectType()
        {
        	return new IDEObjectType();
        }
        
        // Class representing an object type in the IDE
        function IDEObjectType()
        {
        	assert2(this instanceof arguments.callee, "Constructor called as a function");
        }
        
        // Called by IDE when a new object instance of this type is to be created
        IDEObjectType.prototype.CreateInstance = function(instance)
        {
        	return new IDEInstance(instance);
        }
        
        // Class representing an individual instance of an object in the IDE
        function IDEInstance(instance, type)
        {
        	assert2(this instanceof arguments.callee, "Constructor called as a function");
        	
        	// Save the constructor parameters
        	this.instance = instance;
        	this.type = type;
        	
        	// Set the default property values from the property table
        	this.properties = {};
        	
        	for (var i = 0; i < property_list.length; i++)
        		this.properties[property_list[i].name] = property_list[i].initial_value;
        		
        	// Plugin-specific variables
        	this.just_inserted = false;
        	this.font = null;
        }
        
        IDEInstance.prototype.OnCreate = function()
        {
        	this.instance.SetHotspot(new cr.vector2(0, 0));
        }
        
        IDEInstance.prototype.OnInserted = function()
        {
        	this.instance.SetSize(new cr.vector2(150, 22));
        }
        
        IDEInstance.prototype.OnDoubleClicked = function()
        {
        }
        
        // Called by the IDE after a property has been changed
        IDEInstance.prototype.OnPropertyChanged = function(property_name)
        {
        }
        
        IDEInstance.prototype.OnRendererInit = function(renderer)
        {
        }
        	
        // Called to draw self in the editor
        IDEInstance.prototype.Draw = function(renderer)
        {
        	if (!this.font)
        		this.font = renderer.CreateFont("Arial", 14, false, false);
        		
        	renderer.SetTexture(null);
        	var quad = this.instance.GetBoundingQuad();
        	renderer.Fill(quad, this.properties["Enabled"] === "Yes" ? cr.RGB(255, 255, 255) : cr.RGB(224, 224, 224));
        	renderer.Outline(quad, cr.RGB(0, 0, 0));
        	
        	cr.quad.prototype.offset.call(quad, 4, 2);
        	
        	this.font.DrawText(this.properties["Items"].replace(/;/g, "\n"),
        							quad,
        							cr.RGB(0, 0, 0),
        							ha_left);
        
        }
        
        IDEInstance.prototype.OnRendererReleased = function(renderer)
        {
        	this.font = null;
        }
        [/code:20rxu6ru]
        
        [b]runtime[/b]
        [code:20rxu6ru]
        // ECMAScript 5 strict mode
        "use strict";
        // Dropbox , Grey , Bootstap Theme dont have Sort icons
        assert2(cr, "cr namespace not created");
        assert2(cr.plugins_, "cr.plugins_ not created");
        
        /////////////////////////////////////
        // Plugin class
        cr.plugins_.Listview = function(runtime)
        {
        	this.runtime = runtime;
        };
        
        (function ()
        {
        	/////////////////////////////////////
        	var pluginProto = cr.plugins_.Listview.prototype;
        		
        	/////////////////////////////////////
        	// Object type class
        	pluginProto.Type = function(plugin)
        	{
        		this.plugin = plugin;
        		this.runtime = plugin.runtime;
        	};
        
        	var typeProto = pluginProto.Type.prototype;
        
        	// called on startup for each object type
        	typeProto.onCreate = function()
        	{
        	};
        
        	/////////////////////////////////////
        	// Instance class
        	pluginProto.Instance = function(type)
        	{
        		this.type = type;
        		this.runtime = type.runtime;
        	};
        	
        	var instanceProto = pluginProto.Instance.prototype;
        
        	/////////////////////////////////////
        	// PlayLive vars
        	var header = [];
        	var lenCol = [];
        	var align = "";
        	var valign = "";
        	
        	// called whenever an instance is created
        	instanceProto.onCreate = function()
        	{
        		// Not supported in DC
        		if (this.runtime.isDomFree)
        		{
        			cr.logexport("[Construct 2] List plugin not supported on this platform - the object will not be created");
        			return;
        		}
        	
        		this.elem = document.createElement("div");
        		this.elem.table = document.createElement("table");
        		this.elem.id = this.properties[4];
        		if($.trim(this.elem.id) <= 0)
        		{
        			this.elem.id = makeid();
        		}
        		this.lastSelection = -1 ;
        
        		$(this.elem).appendTo(this.runtime.canvasdiv ? this.runtime.canvasdiv : "body");
        		
        		// PlayLive
        		if(this.properties[16] == 0)
        			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","auto").css("padding","0px").css("margin","0px");
        		else if(this.properties[16] == 1)
        			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","scroll").css("padding","0px").css("margin","0px");
        		else if(this.properties[16] == 2)
        			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","hidden").css("padding","0px").css("margin","0px");
        		
        		var self = this;
        		var ligne = [];
        		var theme = "";
        		
        		if($.trim(self.properties[0]).length>0)
        		{
        			if(self.properties[0][self.properties[0].length-1] == ":")
        				self.properties[0]= self.properties[0].slice(0,-1);
        			header=self.properties[0].split(":");
        		}
        		
        		if($.trim(self.properties[1]).length>0)
        		{
        			if(self.properties[1][self.properties[1].length-1] == ";")
        				self.properties[1]= self.properties[1].slice(0,-1);
        			ligne=self.properties[1].split(";");
        		}
        		
        		if($.trim(self.properties[2]).length>0)
        		{
        			if(self.properties[2][self.properties[2].length-1] == ":")
        				self.properties[2]= self.properties[2].slice(0,-1);
        			lenCol=self.properties[2].split(":");
        		}
        		
        		switch(self.properties[8])
        		{
        			case 0 : align="left";break;
        			case 1 : align="center";break;
        			case 2 : align="right";break;
        			default : align="center";break;
        		}
        		switch(self.properties[9])
        		{
        			case 0 : valign="top";break;
        			case 1 : valign="center";break;
        			case 2 : valign="bottom";break;
        			default : valign="center";break;
        		}
        		
        		
        		this.align = align;
        		this.valign = valign;
        		//$(self.elem.table).addClass("tablesorter");
        		
        		
        		$(self.elem.table).attr({
        							"border":self.properties[10],
        							"cellpadding":"0px",
        							"cellspacing":"0px",
        							"width":"100%"
        		}).css("color","black");
        
        		if(header.length>0)
        		{
        			$(self.elem.table).append("<thead><tr></tr></thead>");
        			for(var i=0 ; i<header.length ; i++)
        			{
        				$(this.elem.table).find("thead tr").append("<th width='"+lenCol[i]+"' colNum='"+i+"' align='"+align+"' valign='"+valign+"' >"+header[i]+"</th>");
        			}
        		}
        		
        		$(self.elem.table).append("<tbody></tbody>");
        		if(ligne.length>0)
        		{
        			for(var i=0 ; i<ligne.length ; i++)
        			{
        				var rowId = "";
        				do
        				{
        					rowId = makeid();
        				}while( $("#"+rowId).length);
        				var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
        				var a = ligne[i].split(":");
        				for(var j=0 ; j<a.length ; j++)
        				{
        					if($.trim(self.properties[7]).length >0)
        						LigneToAdd.append("<td align='"+align+"' valign='"+valign+"' style='"+self.properties[7]+"'>"+a[j]+"</td>");
        					else
        						LigneToAdd.append("<td align='"+align+"' valign='"+valign+"'>"+a[j]+"</td>");
        				}
        				$(self.elem.table).find("tbody").append(LigneToAdd);
        			}
        		}
        
        		if($.trim(self.properties[5]).length >0)
        			$(self.elem.table).find("thead tr").attr("style",self.properties[5]);
        		if($.trim(self.properties[6]).length >0)
        			$(self.elem.table).find("tbody tr").attr("style",self.properties[6]);
        		
        		if( self.properties[14] == 1)
        		{
        			if(self.properties[15] > 0)
        			{
        				switch(self.properties[15])
        				{
        					case 0 : theme="none";break;
        					case 1 : theme="blackice";break;
        					case 2 : theme="blue";break;
        					case 3 : theme="bootstrap";break;
        					case 4 : theme="bootstrap_2";break;
        					case 5 : theme="dark";break;
        					case 6 : theme="default";break;
        					case 7 : theme="dropbox";break;
        					case 8 : theme="green";break;
        					case 9 : theme="grey";break;
        					case 10 : theme="ice";break;
        					case 11 : theme="jui";break;
        					default : theme="default";break;
        				}
        				$(self.elem.table).tablesorter(
        				{
        					theme:theme
        				});
        			}
        			else
        			{
        				$(self.elem.table).tablesorter().removeClass("tablesorter-default");
        			}
        		}
        		else
        		{
        			if(self.properties[15] > 0)
        			{
        				switch(self.properties[15])
        				{
        					case 0 : theme="none";break;
        					case 1 : theme="blackice";break;
        					case 2 : theme="blue";break;
        					case 3 : theme="bootstrap";break;
        					case 4 : theme="bootstrap_2";break;
        					case 5 : theme="dark";break;
        					case 6 : theme="default";break;
        					case 7 : theme="dropbox";break;
        					case 8 : theme="green";break;
        					case 9 : theme="grey";break;
        					case 10 : theme="ice";break;
        					case 11 : theme="jui";break;
        					default : theme="default";break;
        				}
        				$(self.elem.table).addClass("tablesorter-"+theme);
        			}
        		}
        
        		// PlayLive
        		if( self.properties[13] == 1)
        			$(self.elem.table).stickyTableHeaders({ scrollableArea: $(".scrollable-area-"+this.elem.id) })
        
        		var sorterAlign = 2;
        		var sorterVisib = "initial";
        
        		switch(self.properties[12])
        		{
        			case 0 : sorterAlign="left";break;
        			case 1 : sorterAlign="center";break;
        			case 2 : sorterAlign="right";break;
        			default : sorterVisib="right";break;
        		}
        
        		$(self.elem.table).find("thead tr .header").css(
        		{
        			"background-position":"center "+sorterAlign
        		});
        		if( self.properties[11] == 0)
        		{
        			$(self.elem.table).find("thead tr .header").css(
        			{
        				"background-image":"none"
        			});
        		}
        		
        		
        		$(this.elem.table).find("tbody").on('click' , 'tr', function() 
        		{
        			if( parseInt($(this).index()) != self.lastSelection)
        			{
        				self.lastSelection = parseInt($(this).index());
        				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnSelectionChanged, self);
        			}
        		});
        		
        		$(this.elem.table).find("tbody").on('mouseover' , 'tr', function() 
        		{
        			self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnHover, self);
        		});
        		
        		this.elem.onclick = function(e) {
        				e.stopPropagation();
        				self.runtime.isInUserInputEvent = true;
        				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnClicked, self);
        				self.runtime.isInUserInputEvent = false;
        			};
        		
        		this.elem.ondblclick = function(e) {
        				e.stopPropagation();
        				self.runtime.isInUserInputEvent = true;
        				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnDoubleClicked, self);
        				self.runtime.isInUserInputEvent = false;
        			};
        		
        		// Prevent touches reaching the canvas
        		this.elem.addEventListener("touchstart", function (e) {
        			e.stopPropagation();
        		}, false);
        		
        		this.elem.addEventListener("touchmove", function (e) {
        			e.stopPropagation();
        		}, false);
        		
        		this.elem.addEventListener("touchend", function (e) {
        			e.stopPropagation();
        		}, false);
        		
        		// Prevent clicks being blocked
        		jQuery(this.elem).mousedown(function (e) {
        			e.stopPropagation();
        		});
        		
        		jQuery(this.elem).mouseup(function (e) {
        			e.stopPropagation();
        		});
        		
        		this.lastLeft = 0;
        		this.lastTop = 0;
        		this.lastRight = 0;
        		this.lastBottom = 0;
        		this.lastWinWidth = 0;
        		this.lastWinHeight = 0;
        		this.isVisible = true;
        		
        		this.updatePosition(true);
        		
        		this.runtime.tickMe(this);
        	};
        	
        	instanceProto.saveToJSON = function ()
        	{
        		var o = {
        			"tooltip": this.elem.title,
        			"disabled": !!this.elem.disabled,
        			"items": [],
        			"sel": []
        		};
        		
        		var i, len;
        		var itemsarr = o["items"];
        		
        		for (i = 0, len = this.elem.length; i < len; i++)
        		{
        			itemsarr.push(this.elem.options[i].text);
        		}
        		
        		var selarr = o["sel"];
        		
        		if (this.elem["multiple"])
        		{
        			for (i = 0, len = this.elem.length; i < len; i++)
        			{
        				if (this.elem.options[i].selected)
        					selarr.push(i);
        			}
        		}
        		else
        		{
        			selarr.push(this.elem["selectedIndex"]);
        		}
        		
        		return o;
        	};
        	
        	instanceProto.loadFromJSON = function (o)
        	{
        		this.elem.title = o["tooltip"];
        		this.elem.disabled = o["disabled"];
        		
        		var itemsarr = o["items"];
        		
        		// Clear the list
        		while (this.elem.length)
        			this.elem.remove(this.elem.length - 1);
        			
        		var i, len, opt;
        		for (i = 0, len = itemsarr.length; i < len; i++)
        		{
        			opt = document.createElement("option");
        			opt.text = itemsarr[i];
        			this.elem.add(opt);
        		}
        		
        		var selarr = o["sel"];
        		
        		if (this.elem["multiple"])
        		{
        			for (i = 0, len = selarr.length; i < len; i++)
        			{
        				if (selarr[i] < this.elem.length)
        					this.elem.options[selarr[i]].selected = true;
        			}
        		}
        		else if (selarr.length >= 1)
        		{
        			this.elem["selectedIndex"] = selarr[0];
        		}
        	};
        	
        	instanceProto.onDestroy = function ()
        	{
        		if (this.runtime.isDomFree)
        				return;
        		
        		jQuery(this.elem).remove();
        		this.elem = null;
        	};
        	
        	instanceProto.tick = function ()
        	{
        		this.updatePosition();
        	};
        	
        	instanceProto.updatePosition = function (first)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		var left = this.layer.layerToCanvas(this.x, this.y, true);
        		var top = this.layer.layerToCanvas(this.x, this.y, false);
        		var right = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, true);
        		var bottom = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, false);
        		
        		var rightEdge = this.runtime.width / this.runtime.devicePixelRatio;
        		var bottomEdge = this.runtime.height / this.runtime.devicePixelRatio;
        		
        		// Is entirely offscreen or invisible: hide
        		if (!this.visible || !this.layer.visible || right <= 0 || bottom <= 0 || left >= rightEdge || top >= bottomEdge)
        		{
        			if (this.isVisible)
        				jQuery(this.elem).hide();
        			
        			this.isVisible = false;
        			return;
        		}
        		
        		// Truncate to canvas size
        		if (left < 1)
        			left = 1;
        		if (top < 1)
        			top = 1;
        		if (right >= rightEdge)
        			right = rightEdge - 1;
        		if (bottom >= bottomEdge)
        			bottom = bottomEdge - 1;
        		
        		var curWinWidth = window.innerWidth;
        		var curWinHeight = window.innerHeight;
        			
        		// Avoid redundant updates
        		if (!first && this.lastLeft === left && this.lastTop === top && this.lastRight === right && this.lastBottom === bottom && this.lastWinWidth === curWinWidth && this.lastWinHeight === curWinHeight)
        		{
        			if (!this.isVisible)
        			{
        				jQuery(this.elem).show();
        				this.isVisible = true;
        			}
        			
        			return;
        		}
        			
        		this.lastLeft = left;
        		this.lastTop = top;
        		this.lastRight = right;
        		this.lastBottom = bottom;
        		this.lastWinWidth = curWinWidth;
        		this.lastWinHeight = curWinHeight;
        		
        		if (!this.isVisible)
        		{
        			jQuery(this.elem).show();
        			this.isVisible = true;
        		}
        		
        		var offx = Math.round(left) + jQuery(this.runtime.canvas).offset().left;
        		var offy = Math.round(top) + jQuery(this.runtime.canvas).offset().top;
        		jQuery(this.elem).css("position", "absolute");
        		jQuery(this.elem).offset({left: offx, top: offy});
        		jQuery(this.elem).width(Math.round(right - left));
        		jQuery(this.elem).height(Math.round(bottom - top));
        		
        	};
        	
        	// only called if a layout object
        	instanceProto.draw = function(ctx)
        	{
        	};
        	
        	instanceProto.drawGL = function(glw)
        	{
        	};
        	
        	/**BEGIN-PREVIEWONLY**/
        	instanceProto.getDebuggerValues = function (propsections)
        	{
        		propsections.push({
        			"title": "List",
        			"properties": [
        				{"name": "Item count", "value": this.elem.length, "readonly": true},
        				{"name": "Enabled", "value": !this.elem.disabled},
        				{"name": "Tooltip", "value": this.elem.title},
        				{"name": "Selected index", "value": this.elem.selectedIndex}
        			]
        		});
        		
        		var props = [], i, len;
        		for (i = 0, len = this.elem.length; i < len; ++i)
        		{
        			props.push({"name": i.toString(), "value": this.elem.options[i].text});
        		}
        		
        		propsections.push({
        			"title": "Items",
        			"properties": props
        		});
        	};
        	
        	instanceProto.onDebugValueEdited = function (header, name, value)
        	{
        		if (header === "List")
        		{
        			switch (name) {
        			case "Enabled":
        				this.elem.disabled = !value;
        				break;
        			case "Tooltip":
        				this.elem.title = value;
        				break;
        			case "Selected index":
        				this.elem.selectedIndex = value;
        				break;
        			}
        		}
        		else if (header === "Items")
        		{
        			this.elem.options[parseInt(name, 10)].text = value;
        		}
        	};
        	/**END-PREVIEWONLY**/
        
        	//////////////////////////////////////
        	// Conditions
        	function Cnds() {};
        	
        	Cnds.prototype.OnSelectionChanged = function ()
        	{
        		return true;
        	};
        	
        	Cnds.prototype.OnClicked = function ()
        	{
        		return true;
        	};
        	
        	Cnds.prototype.OnDoubleClicked = function ()
        	{
        		return true;
        	};
        	
        	Cnds.prototype.OnHover = function ()
        	{
        		return true;
        	};
        	
        	
        	pluginProto.cnds = new Cnds();
        	
        	//////////////////////////////////////
        	// Actions
        	function Acts() {};
        	
        	Acts.prototype.SelectedRow = function (i)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		this.lastSelection = i;
        		$(this.elem.table).find("tbody tr.selected").removeClass("selected");
        		$(this.elem.table).find("tbody tr").eq(i).addClass("selected");
        	};
        	
        	Acts.prototype.SetVisible = function (vis)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		this.visible = (vis !== 0);
        	};
        	
        	Acts.prototype.SetFocus = function ()
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		this.elem.table.focus();
        	};
        	
        	Acts.prototype.SetBlur = function ()
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		this.elem.table.blur();
        	};
        
        	
        	Acts.prototype.AddRow = function (text_)
        	{
        		if (this.runtime.isDomFree)
        			return;
        
        		var rowId = "";
        		do { rowId = makeid(); }
        		while( $("#"+rowId).length);
        		
        		
        		var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
        		var a = text_.split(":");
        		var r = a.toString().replace(/\\,/g, ":");
        		a = r.split(",");
        
        		for(var j=0 ; j<a.length ; j++)
        		{
        			LigneToAdd.append("<td align='"+this.align+"' valign='"+this.valign+"' style='"+this.properties[7]+"'>"+a[j]+"</td>");
        		}
        
        		$(this.elem.table).find("tbody").append(LigneToAdd);
        
        		if( this.properties[14] == 1)
        		{
        			$(this.elem.table).trigger('update');     
        			$(this.elem.table).trigger("sorton",[$(this.elem.table).get(0).config.sortList]); 
        		}
        	};
        	
        	Acts.prototype.AddRowAt = function (index_, text_)
        	{
        		if (this.runtime.isDomFree)
        			return;
        
        		var rowId = "";
        		do
        		{
        			rowId = makeid();
        		}while( $("#"+rowId).length);
        		
        		
        		var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
        		var a = text_.split(":");
        		var r = a.toString().replace(/,,/g, ":");
        		a = r.split(",");
        		for(var j=0 ; j<a.length ; j++)
        		{
        			LigneToAdd.append("<td align='"+this.align+"' valign='"+this.valign+"' style='"+this.properties[7]+"'>"+a[j]+"</td>");
        		}
        		
        		if(index_ > 0)
        			LigneToAdd.insertBefore($(this.elem.table).find("tbody tr").eq(index_));
        		else
        			LigneToAdd.appendTo($(this.elem.table).find("tbody"));
        		
        		if( this.properties[14] == 1 )
        		{
        			$(this.elem.table).trigger('update');
        			$(this.elem.table).trigger("sorton",[$(this.elem.table).get(0).config.sortList]); 
        		}
        	};
        	
        	Acts.prototype.RemoveAt = function (index_)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		if(index_ == this.lastSelection)
        				this.lastSelection = -1 ;
        
        		$(this.elem.table).find("tbody tr").eq(index_).remove();
        	};
        
        	Acts.prototype.ChangeRowCssAt = function (index_,css)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		var item = $(this.elem.table).find("tbody tr").eq(index_);
        		if(item.is("[style]"))
        			item.attr("style",item.attr("style")+css);
        		else
        			item.attr("style",css);
        	};
        	
        	Acts.prototype.ChangeCellCssAt = function (index_,index_2,css)
        	{
        		if (this.runtime.isDomFree)
        			return;
        
        		var item = $(this.elem.table).find("tbody tr").eq(index_).find("td").eq(index_2);
        		if(item.is("[style]"))
        			item.attr("style",item.attr("style")+css);
        		else
        			item.attr("style",css);
        	};
        	
        	Acts.prototype.StoreValueAt = function (index_,key,val)
        	{
        		if (this.runtime.isDomFree)
        			return;
        
        		$(this.elem.table).find("tbody tr").eq(index_).attr(key,val);
        	};
        	
        	Acts.prototype.sortColumn = function (index_,val)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		$("table").trigger("sorton",[ [[index_,val]] ]);
        		
        	};
        	
        	Acts.prototype.Clear = function ()
        	{
        		$(this.elem.table).find("tbody tr").remove();
        	};
        
        	Acts.prototype.ScrollTop = function () // PlayLive
        	{
        		if (this.runtime.isDomFree)
        			return;
        
                this.elem.scrollTop = 0;
        	};
        
        	Acts.prototype.ScrollBottom = function () // PlayLive
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		this.elem.scrollTop = this.elem.scrollHeight;
        	};
        
        	Acts.prototype.SetHeader = function (str_) // PlayLive
        	{
        		if (this.runtime.isDomFree)
        			return;
        /*
        		var newheader = str_.split(":");
        
        		if (newheader.length > 0)
        		{
        			$(this.elem.table).find("thead tr th").text("");
        			var table = $(this.elem.table).find("thead tr th").length / 2;
        
        			while (newheader.length > table) {
        				$(this.elem.table).find("thead tr").append("<th align='"+align+"' valign='"+valign+"'></th>");
        				table++;
        			}
        
        			while (newheader.length < table) {
        				$(this.elem.table).find("thead tr th:eq("+(table)+")").remove();
        				$(this.elem.table).find("thead tr th:eq("+(table)+")").remove();
        				table--;
        			}
        
        			for (var i = 0; i < table; i++) {
        				$(this.elem.table).find("thead tr th:eq("+i+")").text(newheader[i]);
        			}
        		}
        */
        		var newheader = str_.split(":");
        		$(this.elem.table).find("thead tr th").text("");
        
        		for (var i = 0; i < newheader.length; i++)
        			$(this.elem.table).find("thead tr th:eq("+i+")").text(newheader[i]);
        
        	};
        
        	Acts.prototype.ChangeValue = function (row_, cell_, str_) // PlayLive
        	{
        		$(this.elem.table).find("tbody tr:eq("+row_+") td:eq("+cell_+")").text(str_);
        	};
        	
        	pluginProto.acts = new Acts();
        	
        	//////////////////////////////////////
        	// Expressions
        	function Exps() {};
        	
        	Exps.prototype.RowsCount = function (ret)
        	{
        		if (this.runtime.isDomFree)
        		{
        			ret.set_int(0);
        			return;
        		}
        		
        		ret.set_int($(this.elem.table).find("tbody tr").length);
        	};
        	
        	Exps.prototype.SelectedRowIndex = function (ret)
        	{
        		if (this.runtime.isDomFree)
        		{
        			ret.set_int(0);
        			return;
        		}
        		ret.set_int(this.lastSelection);
        	};
        	
        	Exps.prototype.SubTextSelectedRow = function (ret,SubTextIndex)
        	{
        		if (this.runtime.isDomFree)
        		{
        			ret.set_string("");
        			return;
        		}
        		
        		ret.set_string($(this.elem.table).find("tbody tr").eq(this.lastSelection).find("td").eq(SubTextIndex).text());
        	};
        	
        	
        	Exps.prototype.SubTextAt = function (ret,LigneIndex , SubTextIndex)
        	{
        		if (this.runtime.isDomFree)
        		{
        			ret.set_string("");
        			return;
        		}
        		
        		ret.set_string($(this.elem.table).find("tbody tr").eq(LigneIndex).find("td").eq(SubTextIndex).text() );
        	};
        	
        	
        	Exps.prototype.getValueOfKeyAt = function (ret,RowIndex , Key) // PlayLive
        	{
        		if (this.runtime.isDomFree)
        		{
        			ret.set_string("");
        			return;
        		}
        		
        		ret.set_string($(this.elem.table).find("tbody tr").eq(RowIndex).attr(Key) );
        	};
        	pluginProto.exps = new Exps();
        
        }());
        
        function makeid()
        {
            var text = "";
            var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        	
            for( var i=0; i < 10; i++ )
                text += possible.charAt(Math.floor(Math.random() * possible.length));
            return text;
        }
        
        function createCSSSelector(selector, style) 
        {
        	var cssrules =  $("<style type='text/css'> </style>").appendTo("head");
        	cssrules.append(selector+"{ "+style+" }"); 
        }
        [/code:20rxu6ru]
      • andykenobi

        *Sorry for the delay.

        [quote:3oll0gef]

        • Add Set Header (*not stable with fixed header).
        • Add Change Value.

        edittime

        function GetPluginSettings() 
        {
        	return {
        		"name":		"Listview",
        		"id":			"Listview",
        		"version":		"1.3.2",
        		"version modified":		"2",
        		"description":	"Listview.",
        		"author":		"HMMG",
        		"modified by":	"PlayLive",
        		"help url":		"https://www.scirra.com/forum/plugin-listview-header-sorting_t124360",
        		"category":	"Addon",
        		"type":		"world",			// appears in layout
        		"rotatable":	false,
        		"flags":		pf_position_aces | pf_size_aces,
        		"dependency":"jquery.stickytableheaders.min.js;jquery.tablesorter.js;"+
        						"theme.black-ice.css;"+
        						"theme.blue.css;"+
        						"theme.bootstrap.css;"+
        						"theme.bootstrap_2.css;"+
        						"theme.dark.css;"+
        						"theme.default.css;"+
        						"theme.dropbox.css;"+
        						"theme.green.css;"+
        						"theme.grey.css;"+
        						"theme.ice.css;"+
        						"theme.jui.css;"
        	};
        };
        
        ////////////////////////////////////////
        // Parameter types:
        // AddNumberParam(label, description [, initial_string = "0"])			// a number
        // AddStringParam(label, description [, initial_string = "\"\""])		// a string
        // AddAnyTypeParam(label, description [, initial_string = "0"])			// accepts either a number or string
        // AddCmpParam(label, description)										// combo with equal, not equal, less, etc.
        // AddComboParamOption(text)											// (repeat before "AddComboParam" to add combo items)
        // AddComboParam(label, description [, initial_selection = 0])			// a dropdown list parameter
        // AddObjectParam(label, description)									// a button to click and pick an object type
        // AddLayerParam(label, description)									// accepts either a layer number or name (string)
        // AddLayoutParam(label, description)									// a dropdown list with all project layouts
        // AddKeybParam(label, description)										// a button to click and press a key (returns a VK)
        // AddAnimationParam(label, description)								// a string intended to specify an animation name
        // AddAudioFileParam(label, description)								// a dropdown list with all imported project audio files
        
        ////////////////////////////////////////
        // Conditions
        
        // AddCondition(id,					// any positive integer to uniquely identify this condition
        //				flags,				// (see docs) cf_none, cf_trigger, cf_fake_trigger, cf_static, cf_not_invertible,
        //									// cf_deprecated, cf_incompatible_with_triggers, cf_looping
        //				list_name,			// appears in event wizard list
        //				category,			// category in event wizard list
        //				display_str,		// as appears in event sheet - use {0}, {1} for parameters and also <b></b>, <i></i>
        //				description,		// appears in event wizard dialog when selected
        //				script_name);		// corresponding runtime function name
        				
        
        AddCondition(0, cf_trigger, "On selection changed", "Listview", "On selection changed", "Triggered when the selected ligne changes.", "OnSelectionChanged");
        AddCondition(1, cf_trigger, "On clicked", "Listview", "On clicked", "Triggered when the Listview is clicked.", "OnClicked");
        AddCondition(2, cf_trigger, "On double-clicked", "Listview", "On double-clicked", "Triggered when the Listview is double-clicked.", "OnDoubleClicked");
        AddCondition(3, cf_trigger, "On mouse over", "Listview", "On mouse over", "Triggered when the cursor is over the Listview .", "OnHover");
        
        ////////////////////////////////////////
        // Actions
        
        // AddAction(id,				// any positive integer to uniquely identify this action
        //			 flags,				// (see docs) af_none, af_deprecated
        //			 list_name,			// appears in event wizard list
        //			 category,			// category in event wizard list
        //			 display_str,		// as appears in event sheet - use {0}, {1} for parameters and also <b></b>, <i></i>
        //			 description,		// appears in event wizard dialog when selected
        //			 script_name);		// corresponding runtime function name
        
        AddNumberParam("Index", "The zero-based index of the Row to select.");
        AddAction(0, af_none, "Set selected index", "Row", "Select Row <i>{0}</i>", "Select a Row in the listview.", "SelectedRow");
        
        AddComboParamOption("Invisible");
        AddComboParamOption("Visible");
        AddComboParam("Visibility", "Choose whether to hide or show the listview.");
        AddAction(1, af_none, "Set visible", "Appearance", "Set <b>{0}</b>", "Hide or show the listview.", "SetVisible");
        
        AddAction(2, af_none, "Set focused", "Listview", "Set focused", "Set the input focus to the listview.", "SetFocus");
        AddAction(3, af_none, "Set unfocused", "Listview", "Set unfocused", "Remove the input focus from the listview.", "SetBlur");
        
        AddStringParam("Text", "The Row text to add (to add \":\" use \\:). Exemple 3 Column       \"Item1:Item2:Item3\"");
        AddAction(4, af_none, "Add Row", "Row", "Add Row <i>{0}</i>", "Append a new Row to the listview.", "AddRow");
        
        AddNumberParam("Index", "The zero-based index of the Row to insert before.");
        AddStringParam("Text", "The Row text to add (to add \":\" use \\:). Exemple 3 Column       \"Item1:Item2:Item3\"");
        AddAction(5, af_none, "Add Row at", "Row", "Add Row <i>{1}</i> at index <i>{0}</i>", "Append a new Row to a specific place in the listview.", "AddRowAt");
        
        AddNumberParam("Index", "The zero-based index of the Row to remove.");
        AddAction(6, af_none, "Remove At", "Row", "Remove Row <i>{0}</i>", "Remove a Row from the listview.", "RemoveAt");
        
        AddAction(7, af_none, "Clear", "Row", "Clear all Rows", "Remove all Rows from the listview.", "Clear");
        
        AddNumberParam("Index", "The zero-based index of the Row to Change css.");
        AddStringParam("Css", "Css exemple    \"background-color:blue;color:white;\" .");
        AddAction(8, af_none, "Change Row CSS At", "Row", "Change Row <i>{0}</i> CSS to <i>{1}</i>", "Change a Row css.", "ChangeRowCssAt");
        
        AddNumberParam("Row Index", "The zero-based index of the Row to Change the css.");
        AddNumberParam("Cell Index", "The zero-based index of the Cell to Change the css.");
        AddStringParam("Css", "Css exemple    \"background-color:blue;color:white;\" .");
        AddAction(9, af_none, "Change Cell CSS At Row", "Row", "Change Cell <i>{1}</i> At Row <i>{0}</i> CSS to <i>{2}</i>", "Change a Cell css.", "ChangeCellCssAt");
        
        AddNumberParam("Index", "The zero-based index of the Row to Change add a value to.");
        AddStringParam("Key", "Key name where to store the value in the row");
        AddStringParam("Value", "Value to store.");
        AddAction(10, af_none, "Add Value at Row", "Row", "Set <i>{1}</i> = <i>{2}</i> At <i>{0}</i>", "Store a value.", "StoreValueAt");
        
        AddNumberParam("Index", "The zero-based index of the Column to sort by.");
        AddComboParamOption("Ascendant");
        AddComboParamOption("Descendant");
        AddComboParam("Direction", "Select if the sort is Ascendant or Descendant")
        AddAction(11, af_none, "Sort Column", "Sort", "Sort Column of index <i>{0}</i> , Order <i>{1}</i> ", "Sort Column", "sortColumn");
        
        // PlayLive
        AddAction(12, af_none, "Scroll Top", "Listview", "Scroll top", "Scroll to the top line of this object.", "ScrollTop");
        AddAction(13, af_none, "Scroll bottom", "Listview", "Scroll bottom", "Scroll to the bottom of this object.", "ScrollBottom");
        
        AddStringParam("Text", "Set Header (to add \":\" use \\:). Exemple 3 Column       \"Header1:Header2:Header3\"");
        AddAction(14, af_none, "Set Header", "Listview", "Set the header (<i>{0}</i>)", "Set the header.", "SetHeader");
        
        AddNumberParam("Row Index", "The zero-based index of the Row to change the value.");
        AddNumberParam("Cell Index", "The zero-based index of the Cell to change the value.");
        AddStringParam("Value", "Change value (to add \":\" use \\:).");
        AddAction(15, af_none, "Change Value", "Row", "Change value [{0}][{1}] to (<i>{2}</i>)", "Change value at row and cell.", "ChangeValue");
        
        //////////////////////////////////////// 
        // Expressions
        
        // AddExpression(id,			// any positive integer to uniquely identify this expression
        //				 flags,			// (see docs) ef_none, ef_deprecated, ef_return_number, ef_return_string,
        //								// ef_return_any, ef_variadic_parameters (one return flag must be specified)
        //				 list_name,		// currently ignored, but set as if appeared in event wizard
        //				 category,		// category in expressions panel
        //				 exp_name,		// the expression name after the dot, e.g. "foo" for "myobject.foo" - also the runtime function name
        //				 description);	// description in expressions panel
        
        AddExpression(0, ef_return_number, "", "Listview", "RowsCount", "The number of Rows in the listview.");
        AddExpression(1, ef_return_number, "", "Listview", "SelectedRowIndex", "The zero-based index of the currently selected Row.");
        
        AddNumberParam("SubTextIndex", "subText index to get.");
        AddExpression(2, ef_return_string, "", "Listview", "SubTextSelectedRow", "The subText of the currently selected Row.");
        
        AddNumberParam("RowIndex", "Row number to get.");
        AddNumberParam("SubTextIndex", "subText index to get.");
        AddExpression(3, ef_return_string, "", "Listview", "SubTextAt", "The subText of the Nth Row in the listview.");
        
        AddNumberParam("RowIndex", "Row number to get.");
        AddStringParam("Key", "Key name.");
        AddExpression(4, ef_return_string, "", "Listview", "getValueOfKeyAt", "Get stored value of key at a specific row.");
        
        ACESDone();
        
        // Property grid properties for this plugin
        var property_list = [
        	new cr.Property(ept_text,	"Header",				"",			"The initial listiew's header separeted by colon : Exemple header1:header2:header3"),
        	new cr.Property(ept_text,	"Items",				"",			"The initial listiew of items, separated by semicolons ; and colomuns separeted by colon : .Exemple Row1Col1:Row1Col2:Row1Col3;Row2Col1:Row2Col2:Row2Col3;"),
        	new cr.Property(ept_text,	"Colomun Width",	"",			"Set Listview Colomun Width separated by semicolons ;  .Exemple 20%:50%:30%"),
        	new cr.Property(ept_combo,	"Initial visibility",	"Visible",	"Choose whether the list is visible on startup.", "Invisible|Visible"),
        	new cr.Property(ept_text,	"ID (optional)",		"",			"An ID for the control allowing it to be styled with CSS from the page HTML."),
        	new cr.Property(ept_text,	"Header CSS (optional)",		"",		"Add Some CSS to your Listview's header."),
        	new cr.Property(ept_text,	"Rows CSS (optional)",		"",			"Add Some CSS to your Listview's Rows."),
        	new cr.Property(ept_text,	"Cell CSS (optional)",		"",			"Add Some CSS to your Listview's Cells."),
        	new cr.Property(ept_combo,	"Horizontal Alignement",	"Center",		"Set Columns Alignement.", "Left|Center|Right"),
        	new cr.Property(ept_combo,	"Vertical Alignement",	"Center",		"Set Columns Alignement.", "Top|Center|Bottom"),
        	new cr.Property(ept_combo,	"Show Grid",	"No",		"For listview Grid.", "No|Yes"),
        	new cr.Property(ept_combo,	"Show Sorter",	"Yes",		"Show Sorter Icons.", "No|Yes"),
        	new cr.Property(ept_combo,	"Sorter Alignement",	"Right",		"Sorter Alignement .", "Left|Center|Right"),
        	new cr.Property(ept_combo,	"Fixed Header",	"No",		"Header Fixed when scroll.", "No|Yes"),
        	new cr.Property(ept_combo,	"Allow Sort",	"No",		"Allow Sorting.", "No|Yes"),
        	new cr.Property(ept_combo,	"Theme",	"Default",		"Select Listview Theme.", "None|Black-Ice|Blue|Bootstrap|Bootstrap 2|Dark|Default|Dropbox|Green|Grey|Ice|Jui"),
        	new cr.Property(ept_combo,	"Show Y-Scroll",	"Auto",		"Show Y-Scroll.", "Auto|Yes|No")
        ];
        	
        // Called by IDE when a new object type is to be created
        function CreateIDEObjectType()
        {
        	return new IDEObjectType();
        }
        
        // Class representing an object type in the IDE
        function IDEObjectType()
        {
        	assert2(this instanceof arguments.callee, "Constructor called as a function");
        }
        
        // Called by IDE when a new object instance of this type is to be created
        IDEObjectType.prototype.CreateInstance = function(instance)
        {
        	return new IDEInstance(instance);
        }
        
        // Class representing an individual instance of an object in the IDE
        function IDEInstance(instance, type)
        {
        	assert2(this instanceof arguments.callee, "Constructor called as a function");
        	
        	// Save the constructor parameters
        	this.instance = instance;
        	this.type = type;
        	
        	// Set the default property values from the property table
        	this.properties = {};
        	
        	for (var i = 0; i < property_list.length; i++)
        		this.properties[property_list[i].name] = property_list[i].initial_value;
        		
        	// Plugin-specific variables
        	this.just_inserted = false;
        	this.font = null;
        }
        
        IDEInstance.prototype.OnCreate = function()
        {
        	this.instance.SetHotspot(new cr.vector2(0, 0));
        }
        
        IDEInstance.prototype.OnInserted = function()
        {
        	this.instance.SetSize(new cr.vector2(150, 22));
        }
        
        IDEInstance.prototype.OnDoubleClicked = function()
        {
        }
        
        // Called by the IDE after a property has been changed
        IDEInstance.prototype.OnPropertyChanged = function(property_name)
        {
        }
        
        IDEInstance.prototype.OnRendererInit = function(renderer)
        {
        }
        	
        // Called to draw self in the editor
        IDEInstance.prototype.Draw = function(renderer)
        {
        	if (!this.font)
        		this.font = renderer.CreateFont("Arial", 14, false, false);
        		
        	renderer.SetTexture(null);
        	var quad = this.instance.GetBoundingQuad();
        	renderer.Fill(quad, this.properties["Enabled"] === "Yes" ? cr.RGB(255, 255, 255) : cr.RGB(224, 224, 224));
        	renderer.Outline(quad, cr.RGB(0, 0, 0));
        	
        	cr.quad.prototype.offset.call(quad, 4, 2);
        	
        	this.font.DrawText(this.properties["Items"].replace(/;/g, "\n"),
        							quad,
        							cr.RGB(0, 0, 0),
        							ha_left);
        
        }
        
        IDEInstance.prototype.OnRendererReleased = function(renderer)
        {
        	this.font = null;
        }
        [/code:3oll0gef]
        
        [b]runtime[/b]
        [code:3oll0gef]
        // ECMAScript 5 strict mode
        "use strict";
        // Dropbox , Grey , Bootstap Theme dont have Sort icons
        assert2(cr, "cr namespace not created");
        assert2(cr.plugins_, "cr.plugins_ not created");
        
        /////////////////////////////////////
        // Plugin class
        cr.plugins_.Listview = function(runtime)
        {
        	this.runtime = runtime;
        };
        
        (function ()
        {
        	/////////////////////////////////////
        	var pluginProto = cr.plugins_.Listview.prototype;
        		
        	/////////////////////////////////////
        	// Object type class
        	pluginProto.Type = function(plugin)
        	{
        		this.plugin = plugin;
        		this.runtime = plugin.runtime;
        	};
        
        	var typeProto = pluginProto.Type.prototype;
        
        	// called on startup for each object type
        	typeProto.onCreate = function()
        	{
        	};
        
        	/////////////////////////////////////
        	// Instance class
        	pluginProto.Instance = function(type)
        	{
        		this.type = type;
        		this.runtime = type.runtime;
        	};
        	
        	var instanceProto = pluginProto.Instance.prototype;
        
        	/////////////////////////////////////
        	// PlayLive vars
        	var header = [];
        	var lenCol = [];
        	var align = "";
        	var valign = "";
        	
        	// called whenever an instance is created
        	instanceProto.onCreate = function()
        	{
        		// Not supported in DC
        		if (this.runtime.isDomFree)
        		{
        			cr.logexport("[Construct 2] List plugin not supported on this platform - the object will not be created");
        			return;
        		}
        	
        		this.elem = document.createElement("div");
        		this.elem.table = document.createElement("table");
        		this.elem.id = this.properties[4];
        		if($.trim(this.elem.id) <= 0)
        		{
        			this.elem.id = makeid();
        		}
        		this.lastSelection = -1 ;
        
        		$(this.elem).appendTo(this.runtime.canvasdiv ? this.runtime.canvasdiv : "body");
        		
        		// PlayLive
        		if(this.properties[16] == 0)
        			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","auto").css("padding","0px").css("margin","0px");
        		else if(this.properties[16] == 1)
        			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","scroll").css("padding","0px").css("margin","0px");
        		else if(this.properties[16] == 2)
        			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","hidden").css("padding","0px").css("margin","0px");
        		
        		var self = this;
        		var ligne = [];
        		var theme = "";
        		
        		if($.trim(self.properties[0]).length>0)
        		{
        			if(self.properties[0][self.properties[0].length-1] == ":")
        				self.properties[0]= self.properties[0].slice(0,-1);
        			header=self.properties[0].split(":");
        		}
        		
        		if($.trim(self.properties[1]).length>0)
        		{
        			if(self.properties[1][self.properties[1].length-1] == ";")
        				self.properties[1]= self.properties[1].slice(0,-1);
        			ligne=self.properties[1].split(";");
        		}
        		
        		if($.trim(self.properties[2]).length>0)
        		{
        			if(self.properties[2][self.properties[2].length-1] == ":")
        				self.properties[2]= self.properties[2].slice(0,-1);
        			lenCol=self.properties[2].split(":");
        		}
        		
        		switch(self.properties[8])
        		{
        			case 0 : align="left";break;
        			case 1 : align="center";break;
        			case 2 : align="right";break;
        			default : align="center";break;
        		}
        		switch(self.properties[9])
        		{
        			case 0 : valign="top";break;
        			case 1 : valign="center";break;
        			case 2 : valign="bottom";break;
        			default : valign="center";break;
        		}
        		
        		
        		this.align = align;
        		this.valign = valign;
        		//$(self.elem.table).addClass("tablesorter");
        		
        		
        		$(self.elem.table).attr({
        							"border":self.properties[10],
        							"cellpadding":"0px",
        							"cellspacing":"0px",
        							"width":"100%"
        		}).css("color","black");
        
        		if(header.length>0)
        		{
        			$(self.elem.table).append("<thead><tr></tr></thead>");
        			for(var i=0 ; i<header.length ; i++)
        			{
        				$(this.elem.table).find("thead tr").append("<th width='"+lenCol[i]+"' colNum='"+i+"' align='"+align+"' valign='"+valign+"' >"+header[i]+"</th>");
        			}
        		}
        		
        		$(self.elem.table).append("<tbody></tbody>");
        		if(ligne.length>0)
        		{
        			for(var i=0 ; i<ligne.length ; i++)
        			{
        				var rowId = "";
        				do
        				{
        					rowId = makeid();
        				}while( $("#"+rowId).length);
        				var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
        				var a = ligne[i].split(":");
        				for(var j=0 ; j<a.length ; j++)
        				{
        					if($.trim(self.properties[7]).length >0)
        						LigneToAdd.append("<td align='"+align+"' valign='"+valign+"' style='"+self.properties[7]+"'>"+a[j]+"</td>");
        					else
        						LigneToAdd.append("<td align='"+align+"' valign='"+valign+"'>"+a[j]+"</td>");
        				}
        				$(self.elem.table).find("tbody").append(LigneToAdd);
        			}
        		}
        
        		if($.trim(self.properties[5]).length >0)
        			$(self.elem.table).find("thead tr").attr("style",self.properties[5]);
        		if($.trim(self.properties[6]).length >0)
        			$(self.elem.table).find("tbody tr").attr("style",self.properties[6]);
        		
        		if( self.properties[14] == 1)
        		{
        			if(self.properties[15] > 0)
        			{
        				switch(self.properties[15])
        				{
        					case 0 : theme="none";break;
        					case 1 : theme="blackice";break;
        					case 2 : theme="blue";break;
        					case 3 : theme="bootstrap";break;
        					case 4 : theme="bootstrap_2";break;
        					case 5 : theme="dark";break;
        					case 6 : theme="default";break;
        					case 7 : theme="dropbox";break;
        					case 8 : theme="green";break;
        					case 9 : theme="grey";break;
        					case 10 : theme="ice";break;
        					case 11 : theme="jui";break;
        					default : theme="default";break;
        				}
        				$(self.elem.table).tablesorter(
        				{
        					theme:theme
        				});
        			}
        			else
        			{
        				$(self.elem.table).tablesorter().removeClass("tablesorter-default");
        			}
        		}
        		else
        		{
        			if(self.properties[15] > 0)
        			{
        				switch(self.properties[15])
        				{
        					case 0 : theme="none";break;
        					case 1 : theme="blackice";break;
        					case 2 : theme="blue";break;
        					case 3 : theme="bootstrap";break;
        					case 4 : theme="bootstrap_2";break;
        					case 5 : theme="dark";break;
        					case 6 : theme="default";break;
        					case 7 : theme="dropbox";break;
        					case 8 : theme="green";break;
        					case 9 : theme="grey";break;
        					case 10 : theme="ice";break;
        					case 11 : theme="jui";break;
        					default : theme="default";break;
        				}
        				$(self.elem.table).addClass("tablesorter-"+theme);
        			}
        		}
        
        		// PlayLive
        		if( self.properties[13] == 1)
        			$(self.elem.table).stickyTableHeaders({ scrollableArea: $(".scrollable-area-"+this.elem.id) })
        
        		var sorterAlign = 2;
        		var sorterVisib = "initial";
        
        		switch(self.properties[12])
        		{
        			case 0 : sorterAlign="left";break;
        			case 1 : sorterAlign="center";break;
        			case 2 : sorterAlign="right";break;
        			default : sorterVisib="right";break;
        		}
        
        		$(self.elem.table).find("thead tr .header").css(
        		{
        			"background-position":"center "+sorterAlign
        		});
        		if( self.properties[11] == 0)
        		{
        			$(self.elem.table).find("thead tr .header").css(
        			{
        				"background-image":"none"
        			});
        		}
        		
        		
        		$(this.elem.table).find("tbody").on('click' , 'tr', function() 
        		{
        			if( parseInt($(this).index()) != self.lastSelection)
        			{
        				self.lastSelection = parseInt($(this).index());
        				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnSelectionChanged, self);
        			}
        		});
        		
        		$(this.elem.table).find("tbody").on('mouseover' , 'tr', function() 
        		{
        			self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnHover, self);
        		});
        		
        		this.elem.onclick = function(e) {
        				e.stopPropagation();
        				self.runtime.isInUserInputEvent = true;
        				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnClicked, self);
        				self.runtime.isInUserInputEvent = false;
        			};
        		
        		this.elem.ondblclick = function(e) {
        				e.stopPropagation();
        				self.runtime.isInUserInputEvent = true;
        				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnDoubleClicked, self);
        				self.runtime.isInUserInputEvent = false;
        			};
        		
        		// Prevent touches reaching the canvas
        		this.elem.addEventListener("touchstart", function (e) {
        			e.stopPropagation();
        		}, false);
        		
        		this.elem.addEventListener("touchmove", function (e) {
        			e.stopPropagation();
        		}, false);
        		
        		this.elem.addEventListener("touchend", function (e) {
        			e.stopPropagation();
        		}, false);
        		
        		// Prevent clicks being blocked
        		jQuery(this.elem).mousedown(function (e) {
        			e.stopPropagation();
        		});
        		
        		jQuery(this.elem).mouseup(function (e) {
        			e.stopPropagation();
        		});
        		
        		this.lastLeft = 0;
        		this.lastTop = 0;
        		this.lastRight = 0;
        		this.lastBottom = 0;
        		this.lastWinWidth = 0;
        		this.lastWinHeight = 0;
        		this.isVisible = true;
        		
        		this.updatePosition(true);
        		
        		this.runtime.tickMe(this);
        	};
        	
        	instanceProto.saveToJSON = function ()
        	{
        		var o = {
        			"tooltip": this.elem.title,
        			"disabled": !!this.elem.disabled,
        			"items": [],
        			"sel": []
        		};
        		
        		var i, len;
        		var itemsarr = o["items"];
        		
        		for (i = 0, len = this.elem.length; i < len; i++)
        		{
        			itemsarr.push(this.elem.options[i].text);
        		}
        		
        		var selarr = o["sel"];
        		
        		if (this.elem["multiple"])
        		{
        			for (i = 0, len = this.elem.length; i < len; i++)
        			{
        				if (this.elem.options[i].selected)
        					selarr.push(i);
        			}
        		}
        		else
        		{
        			selarr.push(this.elem["selectedIndex"]);
        		}
        		
        		return o;
        	};
        	
        	instanceProto.loadFromJSON = function (o)
        	{
        		this.elem.title = o["tooltip"];
        		this.elem.disabled = o["disabled"];
        		
        		var itemsarr = o["items"];
        		
        		// Clear the list
        		while (this.elem.length)
        			this.elem.remove(this.elem.length - 1);
        			
        		var i, len, opt;
        		for (i = 0, len = itemsarr.length; i < len; i++)
        		{
        			opt = document.createElement("option");
        			opt.text = itemsarr[i];
        			this.elem.add(opt);
        		}
        		
        		var selarr = o["sel"];
        		
        		if (this.elem["multiple"])
        		{
        			for (i = 0, len = selarr.length; i < len; i++)
        			{
        				if (selarr[i] < this.elem.length)
        					this.elem.options[selarr[i]].selected = true;
        			}
        		}
        		else if (selarr.length >= 1)
        		{
        			this.elem["selectedIndex"] = selarr[0];
        		}
        	};
        	
        	instanceProto.onDestroy = function ()
        	{
        		if (this.runtime.isDomFree)
        				return;
        		
        		jQuery(this.elem).remove();
        		this.elem = null;
        	};
        	
        	instanceProto.tick = function ()
        	{
        		this.updatePosition();
        	};
        	
        	instanceProto.updatePosition = function (first)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		var left = this.layer.layerToCanvas(this.x, this.y, true);
        		var top = this.layer.layerToCanvas(this.x, this.y, false);
        		var right = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, true);
        		var bottom = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, false);
        		
        		var rightEdge = this.runtime.width / this.runtime.devicePixelRatio;
        		var bottomEdge = this.runtime.height / this.runtime.devicePixelRatio;
        		
        		// Is entirely offscreen or invisible: hide
        		if (!this.visible || !this.layer.visible || right <= 0 || bottom <= 0 || left >= rightEdge || top >= bottomEdge)
        		{
        			if (this.isVisible)
        				jQuery(this.elem).hide();
        			
        			this.isVisible = false;
        			return;
        		}
        		
        		// Truncate to canvas size
        		if (left < 1)
        			left = 1;
        		if (top < 1)
        			top = 1;
        		if (right >= rightEdge)
        			right = rightEdge - 1;
        		if (bottom >= bottomEdge)
        			bottom = bottomEdge - 1;
        		
        		var curWinWidth = window.innerWidth;
        		var curWinHeight = window.innerHeight;
        			
        		// Avoid redundant updates
        		if (!first && this.lastLeft === left && this.lastTop === top && this.lastRight === right && this.lastBottom === bottom && this.lastWinWidth === curWinWidth && this.lastWinHeight === curWinHeight)
        		{
        			if (!this.isVisible)
        			{
        				jQuery(this.elem).show();
        				this.isVisible = true;
        			}
        			
        			return;
        		}
        			
        		this.lastLeft = left;
        		this.lastTop = top;
        		this.lastRight = right;
        		this.lastBottom = bottom;
        		this.lastWinWidth = curWinWidth;
        		this.lastWinHeight = curWinHeight;
        		
        		if (!this.isVisible)
        		{
        			jQuery(this.elem).show();
        			this.isVisible = true;
        		}
        		
        		var offx = Math.round(left) + jQuery(this.runtime.canvas).offset().left;
        		var offy = Math.round(top) + jQuery(this.runtime.canvas).offset().top;
        		jQuery(this.elem).css("position", "absolute");
        		jQuery(this.elem).offset({left: offx, top: offy});
        		jQuery(this.elem).width(Math.round(right - left));
        		jQuery(this.elem).height(Math.round(bottom - top));
        		
        	};
        	
        	// only called if a layout object
        	instanceProto.draw = function(ctx)
        	{
        	};
        	
        	instanceProto.drawGL = function(glw)
        	{
        	};
        	
        	/**BEGIN-PREVIEWONLY**/
        	instanceProto.getDebuggerValues = function (propsections)
        	{
        		propsections.push({
        			"title": "List",
        			"properties": [
        				{"name": "Item count", "value": this.elem.length, "readonly": true},
        				{"name": "Enabled", "value": !this.elem.disabled},
        				{"name": "Tooltip", "value": this.elem.title},
        				{"name": "Selected index", "value": this.elem.selectedIndex}
        			]
        		});
        		
        		var props = [], i, len;
        		for (i = 0, len = this.elem.length; i < len; ++i)
        		{
        			props.push({"name": i.toString(), "value": this.elem.options[i].text});
        		}
        		
        		propsections.push({
        			"title": "Items",
        			"properties": props
        		});
        	};
        	
        	instanceProto.onDebugValueEdited = function (header, name, value)
        	{
        		if (header === "List")
        		{
        			switch (name) {
        			case "Enabled":
        				this.elem.disabled = !value;
        				break;
        			case "Tooltip":
        				this.elem.title = value;
        				break;
        			case "Selected index":
        				this.elem.selectedIndex = value;
        				break;
        			}
        		}
        		else if (header === "Items")
        		{
        			this.elem.options[parseInt(name, 10)].text = value;
        		}
        	};
        	/**END-PREVIEWONLY**/
        
        	//////////////////////////////////////
        	// Conditions
        	function Cnds() {};
        	
        	Cnds.prototype.OnSelectionChanged = function ()
        	{
        		return true;
        	};
        	
        	Cnds.prototype.OnClicked = function ()
        	{
        		return true;
        	};
        	
        	Cnds.prototype.OnDoubleClicked = function ()
        	{
        		return true;
        	};
        	
        	Cnds.prototype.OnHover = function ()
        	{
        		return true;
        	};
        	
        	
        	pluginProto.cnds = new Cnds();
        	
        	//////////////////////////////////////
        	// Actions
        	function Acts() {};
        	
        	Acts.prototype.SelectedRow = function (i)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		this.lastSelection = i;
        		$(this.elem.table).find("tbody tr.selected").removeClass("selected");
        		$(this.elem.table).find("tbody tr").eq(i).addClass("selected");
        	};
        	
        	Acts.prototype.SetVisible = function (vis)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		this.visible = (vis !== 0);
        	};
        	
        	Acts.prototype.SetFocus = function ()
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		this.elem.table.focus();
        	};
        	
        	Acts.prototype.SetBlur = function ()
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		this.elem.table.blur();
        	};
        
        	
        	Acts.prototype.AddRow = function (text_)
        	{
        		if (this.runtime.isDomFree)
        			return;
        
        		var rowId = "";
        		do { rowId = makeid(); }
        		while( $("#"+rowId).length);
        		
        		
        		var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
        		var a = text_.split(":");
        		var r = a.toString().replace(/\\,/g, ":");
        		a = r.split(",");
        
        		for(var j=0 ; j<a.length ; j++)
        		{
        			LigneToAdd.append("<td align='"+this.align+"' valign='"+this.valign+"' style='"+this.properties[7]+"'>"+a[j]+"</td>");
        		}
        
        		$(this.elem.table).find("tbody").append(LigneToAdd);
        
        		if( this.properties[14] == 1)
        		{
        			$(this.elem.table).trigger('update');     
        			$(this.elem.table).trigger("sorton",[$(this.elem.table).get(0).config.sortList]); 
        		}
        	};
        	
        	Acts.prototype.AddRowAt = function (index_, text_)
        	{
        		if (this.runtime.isDomFree)
        			return;
        
        		var rowId = "";
        		do
        		{
        			rowId = makeid();
        		}while( $("#"+rowId).length);
        		
        		
        		var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
        		var a = text_.split(":");
        		var r = a.toString().replace(/,,/g, ":");
        		a = r.split(",");
        		for(var j=0 ; j<a.length ; j++)
        		{
        			LigneToAdd.append("<td align='"+this.align+"' valign='"+this.valign+"' style='"+this.properties[7]+"'>"+a[j]+"</td>");
        		}
        		
        		if(index_ > 0)
        			LigneToAdd.insertBefore($(this.elem.table).find("tbody tr").eq(index_));
        		else
        			LigneToAdd.appendTo($(this.elem.table).find("tbody"));
        		
        		if( this.properties[14] == 1 )
        		{
        			$(this.elem.table).trigger('update');
        			$(this.elem.table).trigger("sorton",[$(this.elem.table).get(0).config.sortList]); 
        		}
        	};
        	
        	Acts.prototype.RemoveAt = function (index_)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		if(index_ == this.lastSelection)
        				this.lastSelection = -1 ;
        
        		$(this.elem.table).find("tbody tr").eq(index_).remove();
        	};
        
        	Acts.prototype.ChangeRowCssAt = function (index_,css)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		var item = $(this.elem.table).find("tbody tr").eq(index_);
        		if(item.is("[style]"))
        			item.attr("style",item.attr("style")+css);
        		else
        			item.attr("style",css);
        	};
        	
        	Acts.prototype.ChangeCellCssAt = function (index_,index_2,css)
        	{
        		if (this.runtime.isDomFree)
        			return;
        
        		var item = $(this.elem.table).find("tbody tr").eq(index_).find("td").eq(index_2);
        		if(item.is("[style]"))
        			item.attr("style",item.attr("style")+css);
        		else
        			item.attr("style",css);
        	};
        	
        	Acts.prototype.StoreValueAt = function (index_,key,val)
        	{
        		if (this.runtime.isDomFree)
        			return;
        
        		$(this.elem.table).find("tbody tr").eq(index_).attr(key,val);
        	};
        	
        	Acts.prototype.sortColumn = function (index_,val)
        	{
        		if (this.runtime.isDomFree)
        			return;
        		$("table").trigger("sorton",[ [[index_,val]] ]);
        		
        	};
        	
        	Acts.prototype.Clear = function ()
        	{
        		$(this.elem.table).find("tbody tr").remove();
        	};
        
        	Acts.prototype.ScrollTop = function () // PlayLive
        	{
        		if (this.runtime.isDomFree)
        			return;
        
                this.elem.scrollTop = 0;
        	};
        
        	Acts.prototype.ScrollBottom = function () // PlayLive
        	{
        		if (this.runtime.isDomFree)
        			return;
        		
        		this.elem.scrollTop = this.elem.scrollHeight;
        	};
        
        	Acts.prototype.SetHeader = function (str_) // PlayLive
        	{
        		if (this.runtime.isDomFree)
        			return;
        /*
        		var newheader = str_.split(":");
        
        		if (newheader.length > 0)
        		{
        			$(this.elem.table).find("thead tr th").text("");
        			var table = $(this.elem.table).find("thead tr th").length / 2;
        
        			while (newheader.length > table) {
        				$(this.elem.table).find("thead tr").append("<th align='"+align+"' valign='"+valign+"'></th>");
        				table++;
        			}
        
        			while (newheader.length < table) {
        				$(this.elem.table).find("thead tr th:eq("+(table)+")").remove();
        				$(this.elem.table).find("thead tr th:eq("+(table)+")").remove();
        				table--;
        			}
        
        			for (var i = 0; i < table; i++) {
        				$(this.elem.table).find("thead tr th:eq("+i+")").text(newheader[i]);
        			}
        		}
        */
        		var newheader = str_.split(":");
        		$(this.elem.table).find("thead tr th").text("");
        
        		for (var i = 0; i < newheader.length; i++)
        			$(this.elem.table).find("thead tr th:eq("+i+")").text(newheader[i]);
        
        	};
        
        	Acts.prototype.ChangeValue = function (row_, cell_, str_) // PlayLive
        	{
        		$(this.elem.table).find("tbody tr:eq("+row_+") td:eq("+cell_+")").text(str_);
        	};
        	
        	pluginProto.acts = new Acts();
        	
        	//////////////////////////////////////
        	// Expressions
        	function Exps() {};
        	
        	Exps.prototype.RowsCount = function (ret)
        	{
        		if (this.runtime.isDomFree)
        		{
        			ret.set_int(0);
        			return;
        		}
        		
        		ret.set_int($(this.elem.table).find("tbody tr").length);
        	};
        	
        	Exps.prototype.SelectedRowIndex = function (ret)
        	{
        		if (this.runtime.isDomFree)
        		{
        			ret.set_int(0);
        			return;
        		}
        		ret.set_int(this.lastSelection);
        	};
        	
        	Exps.prototype.SubTextSelectedRow = function (ret,SubTextIndex)
        	{
        		if (this.runtime.isDomFree)
        		{
        			ret.set_string("");
        			return;
        		}
        		
        		ret.set_string($(this.elem.table).find("tbody tr").eq(this.lastSelection).find("td").eq(SubTextIndex).text());
        	};
        	
        	
        	Exps.prototype.SubTextAt = function (ret,LigneIndex , SubTextIndex)
        	{
        		if (this.runtime.isDomFree)
        		{
        			ret.set_string("");
        			return;
        		}
        		
        		ret.set_string($(this.elem.table).find("tbody tr").eq(LigneIndex).find("td").eq(SubTextIndex).text() );
        	};
        	
        	
        	Exps.prototype.getValueOfKeyAt = function (ret,RowIndex , Key) // PlayLive
        	{
        		if (this.runtime.isDomFree)
        		{
        			ret.set_string("");
        			return;
        		}
        		
        		ret.set_string($(this.elem.table).find("tbody tr").eq(RowIndex).attr(Key) );
        	};
        	pluginProto.exps = new Exps();
        
        }());
        
        function makeid()
        {
            var text = "";
            var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        	
            for( var i=0; i < 10; i++ )
                text += possible.charAt(Math.floor(Math.random() * possible.length));
            return text;
        }
        
        function createCSSSelector(selector, style) 
        {
        	var cssrules =  $("<style type='text/css'> </style>").appendTo("head");
        	cssrules.append(selector+"{ "+style+" }"); 
        }
        [/code:3oll0gef]
        
        
        Thanks for the update!
        
        Does someone can tell me how to fill the listview with a JSON as source? oO Somehow I cant manage that...
      • Thanks, a very useful plugin!

        I need a ScrollRight action for my project, so I used PlayLive's modifications to add two new actions: ScrollLeft and ScrollRight, and it seems to be working ok. Revised version (1.3.3) below.

        edittime.js

        function GetPluginSettings() 
        {
           return {
              "name":      "Listview",
              "id":         "Listview",
              "version":      "1.3.3",
              "version modified":      "2",
              "description":   "Listview.",
              "author":      "HMMG",
              "modified by":   "PlayLive",
              "help url":      "https://www.scirra.com/forum/plugin-listview-header-sorting_t124360",
              "category":   "Addon",
              "type":      "world",         // appears in layout
              "rotatable":   false,
              "flags":      pf_position_aces | pf_size_aces,
              "dependency":"jquery.stickytableheaders.min.js;jquery.tablesorter.js;"+
                          "theme.black-ice.css;"+
                          "theme.blue.css;"+
                          "theme.bootstrap.css;"+
                          "theme.bootstrap_2.css;"+
                          "theme.dark.css;"+
                          "theme.default.css;"+
                          "theme.dropbox.css;"+
                          "theme.green.css;"+
                          "theme.grey.css;"+
                          "theme.ice.css;"+
                          "theme.jui.css;"
           };
        };
        
        ////////////////////////////////////////
        // Parameter types:
        // AddNumberParam(label, description [, initial_string = "0"])         // a number
        // AddStringParam(label, description [, initial_string = "\"\""])      // a string
        // AddAnyTypeParam(label, description [, initial_string = "0"])         // accepts either a number or string
        // AddCmpParam(label, description)                              // combo with equal, not equal, less, etc.
        // AddComboParamOption(text)                                 // (repeat before "AddComboParam" to add combo items)
        // AddComboParam(label, description [, initial_selection = 0])         // a dropdown list parameter
        // AddObjectParam(label, description)                           // a button to click and pick an object type
        // AddLayerParam(label, description)                           // accepts either a layer number or name (string)
        // AddLayoutParam(label, description)                           // a dropdown list with all project layouts
        // AddKeybParam(label, description)                              // a button to click and press a key (returns a VK)
        // AddAnimationParam(label, description)                        // a string intended to specify an animation name
        // AddAudioFileParam(label, description)                        // a dropdown list with all imported project audio files
        
        ////////////////////////////////////////
        // Conditions
        
        // AddCondition(id,               // any positive integer to uniquely identify this condition
        //            flags,            // (see docs) cf_none, cf_trigger, cf_fake_trigger, cf_static, cf_not_invertible,
        //                           // cf_deprecated, cf_incompatible_with_triggers, cf_looping
        //            list_name,         // appears in event wizard list
        //            category,         // category in event wizard list
        //            display_str,      // as appears in event sheet - use {0}, {1} for parameters and also <b></b>, <i></i>
        //            description,      // appears in event wizard dialog when selected
        //            script_name);      // corresponding runtime function name
                    
        
        AddCondition(0, cf_trigger, "On selection changed", "Listview", "On selection changed", "Triggered when the selected ligne changes.", "OnSelectionChanged");
        AddCondition(1, cf_trigger, "On clicked", "Listview", "On clicked", "Triggered when the Listview is clicked.", "OnClicked");
        AddCondition(2, cf_trigger, "On double-clicked", "Listview", "On double-clicked", "Triggered when the Listview is double-clicked.", "OnDoubleClicked");
        AddCondition(3, cf_trigger, "On mouse over", "Listview", "On mouse over", "Triggered when the cursor is over the Listview .", "OnHover");
        
        ////////////////////////////////////////
        // Actions
        
        // AddAction(id,            // any positive integer to uniquely identify this action
        //          flags,            // (see docs) af_none, af_deprecated
        //          list_name,         // appears in event wizard list
        //          category,         // category in event wizard list
        //          display_str,      // as appears in event sheet - use {0}, {1} for parameters and also <b></b>, <i></i>
        //          description,      // appears in event wizard dialog when selected
        //          script_name);      // corresponding runtime function name
        
        AddNumberParam("Index", "The zero-based index of the Row to select.");
        AddAction(0, af_none, "Set selected index", "Row", "Select Row <i>{0}</i>", "Select a Row in the listview.", "SelectedRow");
        
        AddComboParamOption("Invisible");
        AddComboParamOption("Visible");
        AddComboParam("Visibility", "Choose whether to hide or show the listview.");
        AddAction(1, af_none, "Set visible", "Appearance", "Set <b>{0}</b>", "Hide or show the listview.", "SetVisible");
        
        AddAction(2, af_none, "Set focused", "Listview", "Set focused", "Set the input focus to the listview.", "SetFocus");
        AddAction(3, af_none, "Set unfocused", "Listview", "Set unfocused", "Remove the input focus from the listview.", "SetBlur");
        
        AddStringParam("Text", "The Row text to add (to add \":\" use \\:). Exemple 3 Column       \"Item1:Item2:Item3\"");
        AddAction(4, af_none, "Add Row", "Row", "Add Row <i>{0}</i>", "Append a new Row to the listview.", "AddRow");
        
        AddNumberParam("Index", "The zero-based index of the Row to insert before.");
        AddStringParam("Text", "The Row text to add (to add \":\" use \\:). Exemple 3 Column       \"Item1:Item2:Item3\"");
        AddAction(5, af_none, "Add Row at", "Row", "Add Row <i>{1}</i> at index <i>{0}</i>", "Append a new Row to a specific place in the listview.", "AddRowAt");
        
        AddNumberParam("Index", "The zero-based index of the Row to remove.");
        AddAction(6, af_none, "Remove At", "Row", "Remove Row <i>{0}</i>", "Remove a Row from the listview.", "RemoveAt");
        
        AddAction(7, af_none, "Clear", "Row", "Clear all Rows", "Remove all Rows from the listview.", "Clear");
        
        AddNumberParam("Index", "The zero-based index of the Row to Change css.");
        AddStringParam("Css", "Css exemple    \"background-color:blue;color:white;\" .");
        AddAction(8, af_none, "Change Row CSS At", "Row", "Change Row <i>{0}</i> CSS to <i>{1}</i>", "Change a Row css.", "ChangeRowCssAt");
        
        AddNumberParam("Row Index", "The zero-based index of the Row to Change the css.");
        AddNumberParam("Cell Index", "The zero-based index of the Cell to Change the css.");
        AddStringParam("Css", "Css exemple    \"background-color:blue;color:white;\" .");
        AddAction(9, af_none, "Change Cell CSS At Row", "Row", "Change Cell <i>{1}</i> At Row <i>{0}</i> CSS to <i>{2}</i>", "Change a Cell css.", "ChangeCellCssAt");
        
        AddNumberParam("Index", "The zero-based index of the Row to Change add a value to.");
        AddStringParam("Key", "Key name where to store the value in the row");
        AddStringParam("Value", "Value to store.");
        AddAction(10, af_none, "Add Value at Row", "Row", "Set <i>{1}</i> = <i>{2}</i> At <i>{0}</i>", "Store a value.", "StoreValueAt");
        
        AddNumberParam("Index", "The zero-based index of the Column to sort by.");
        AddComboParamOption("Ascendant");
        AddComboParamOption("Descendant");
        AddComboParam("Direction", "Select if the sort is Ascendant or Descendant")
        AddAction(11, af_none, "Sort Column", "Sort", "Sort Column of index <i>{0}</i> , Order <i>{1}</i> ", "Sort Column", "sortColumn");
        
        // PlayLive
        AddAction(12, af_none, "Scroll Top", "Listview", "Scroll top", "Scroll to the top line of this object.", "ScrollTop");
        AddAction(13, af_none, "Scroll Bottom", "Listview", "Scroll bottom", "Scroll to the bottom of this object.", "ScrollBottom");
        
        AddStringParam("Text", "Set Header (to add \":\" use \\:). Exemple 3 Column       \"Header1:Header2:Header3\"");
        AddAction(14, af_none, "Set Header", "Listview", "Set the header (<i>{0}</i>)", "Set the header.", "SetHeader");
        
        AddNumberParam("Row Index", "The zero-based index of the Row to change the value.");
        AddNumberParam("Cell Index", "The zero-based index of the Cell to change the value.");
        AddStringParam("Value", "Change value (to add \":\" use \\:).");
        AddAction(15, af_none, "Change Value", "Row", "Change value [{0}][{1}] to (<i>{2}</i>)", "Change value at row and cell.", "ChangeValue");
        
        // CJK
        AddAction(16, af_none, "Scroll Right", "Listview", "Scroll right", "Scroll to the rightmost cell of this object.", "ScrollRight");
        AddAction(17, af_none, "Scroll Left", "Listview", "Scroll left", "Scroll to the leftmost of this object.", "ScrollLeft");
        
        //////////////////////////////////////// 
        // Expressions
        
        // AddExpression(id,         // any positive integer to uniquely identify this expression
        //             flags,         // (see docs) ef_none, ef_deprecated, ef_return_number, ef_return_string,
        //                        // ef_return_any, ef_variadic_parameters (one return flag must be specified)
        //             list_name,      // currently ignored, but set as if appeared in event wizard
        //             category,      // category in expressions panel
        //             exp_name,      // the expression name after the dot, e.g. "foo" for "myobject.foo" - also the runtime function name
        //             description);   // description in expressions panel
        
        AddExpression(0, ef_return_number, "", "Listview", "RowsCount", "The number of Rows in the listview.");
        AddExpression(1, ef_return_number, "", "Listview", "SelectedRowIndex", "The zero-based index of the currently selected Row.");
        
        AddNumberParam("SubTextIndex", "subText index to get.");
        AddExpression(2, ef_return_string, "", "Listview", "SubTextSelectedRow", "The subText of the currently selected Row.");
        
        AddNumberParam("RowIndex", "Row number to get.");
        AddNumberParam("SubTextIndex", "subText index to get.");
        AddExpression(3, ef_return_string, "", "Listview", "SubTextAt", "The subText of the Nth Row in the listview.");
        
        AddNumberParam("RowIndex", "Row number to get.");
        AddStringParam("Key", "Key name.");
        AddExpression(4, ef_return_string, "", "Listview", "getValueOfKeyAt", "Get stored value of key at a specific row.");
        
        ACESDone();
        
        // Property grid properties for this plugin
        var property_list = [
           new cr.Property(ept_text,   "Header",            "",         "The initial listiew's header separeted by colon : Exemple header1:header2:header3"),
           new cr.Property(ept_text,   "Items",            "",         "The initial listiew of items, separated by semicolons ; and colomuns separeted by colon : .Exemple Row1Col1:Row1Col2:Row1Col3;Row2Col1:Row2Col2:Row2Col3;"),
           new cr.Property(ept_text,   "Colomun Width",   "",         "Set Listview Colomun Width separated by semicolons ;  .Exemple 20%:50%:30%"),
           new cr.Property(ept_combo,   "Initial visibility",   "Visible",   "Choose whether the list is visible on startup.", "Invisible|Visible"),
           new cr.Property(ept_text,   "ID (optional)",      "",         "An ID for the control allowing it to be styled with CSS from the page HTML."),
           new cr.Property(ept_text,   "Header CSS (optional)",      "",      "Add Some CSS to your Listview's header."),
           new cr.Property(ept_text,   "Rows CSS (optional)",      "",         "Add Some CSS to your Listview's Rows."),
           new cr.Property(ept_text,   "Cell CSS (optional)",      "",         "Add Some CSS to your Listview's Cells."),
           new cr.Property(ept_combo,   "Horizontal Alignement",   "Center",      "Set Columns Alignement.", "Left|Center|Right"),
           new cr.Property(ept_combo,   "Vertical Alignement",   "Center",      "Set Columns Alignement.", "Top|Center|Bottom"),
           new cr.Property(ept_combo,   "Show Grid",   "No",      "For listview Grid.", "No|Yes"),
           new cr.Property(ept_combo,   "Show Sorter",   "Yes",      "Show Sorter Icons.", "No|Yes"),
           new cr.Property(ept_combo,   "Sorter Alignement",   "Right",      "Sorter Alignement .", "Left|Center|Right"),
           new cr.Property(ept_combo,   "Fixed Header",   "No",      "Header Fixed when scroll.", "No|Yes"),
           new cr.Property(ept_combo,   "Allow Sort",   "No",      "Allow Sorting.", "No|Yes"),
           new cr.Property(ept_combo,   "Theme",   "Default",      "Select Listview Theme.", "None|Black-Ice|Blue|Bootstrap|Bootstrap 2|Dark|Default|Dropbox|Green|Grey|Ice|Jui"),
           new cr.Property(ept_combo,   "Show Y-Scroll",   "Auto",      "Show Y-Scroll.", "Auto|Yes|No")
        ];
           
        // Called by IDE when a new object type is to be created
        function CreateIDEObjectType()
        {
           return new IDEObjectType();
        }
        
        // Class representing an object type in the IDE
        function IDEObjectType()
        {
           assert2(this instanceof arguments.callee, "Constructor called as a function");
        }
        
        // Called by IDE when a new object instance of this type is to be created
        IDEObjectType.prototype.CreateInstance = function(instance)
        {
           return new IDEInstance(instance);
        }
        
        // Class representing an individual instance of an object in the IDE
        function IDEInstance(instance, type)
        {
           assert2(this instanceof arguments.callee, "Constructor called as a function");
           
           // Save the constructor parameters
           this.instance = instance;
           this.type = type;
           
           // Set the default property values from the property table
           this.properties = {};
           
           for (var i = 0; i < property_list.length; i++)
              this.properties[property_list[i].name] = property_list[i].initial_value;
              
           // Plugin-specific variables
           this.just_inserted = false;
           this.font = null;
        }
        
        IDEInstance.prototype.OnCreate = function()
        {
           this.instance.SetHotspot(new cr.vector2(0, 0));
        }
        
        IDEInstance.prototype.OnInserted = function()
        {
           this.instance.SetSize(new cr.vector2(150, 22));
        }
        
        IDEInstance.prototype.OnDoubleClicked = function()
        {
        }
        
        // Called by the IDE after a property has been changed
        IDEInstance.prototype.OnPropertyChanged = function(property_name)
        {
        }
        
        IDEInstance.prototype.OnRendererInit = function(renderer)
        {
        }
           
        // Called to draw self in the editor
        IDEInstance.prototype.Draw = function(renderer)
        {
           if (!this.font)
              this.font = renderer.CreateFont("Arial", 14, false, false);
              
           renderer.SetTexture(null);
           var quad = this.instance.GetBoundingQuad();
           renderer.Fill(quad, this.properties["Enabled"] === "Yes" ? cr.RGB(255, 255, 255) : cr.RGB(224, 224, 224));
           renderer.Outline(quad, cr.RGB(0, 0, 0));
           
           cr.quad.prototype.offset.call(quad, 4, 2);
           
           this.font.DrawText(this.properties["Items"].replace(/;/g, "\n"),
                             quad,
                             cr.RGB(0, 0, 0),
                             ha_left);
        
        }
        
        IDEInstance.prototype.OnRendererReleased = function(renderer)
        {
           this.font = null;
        }[/code:2fv33rzn]
        
        runtime.js
        
        [code:2fv33rzn]// ECMAScript 5 strict mode
        "use strict";
        // Dropbox , Grey , Bootstap Theme dont have Sort icons
        assert2(cr, "cr namespace not created");
        assert2(cr.plugins_, "cr.plugins_ not created");
        
        /////////////////////////////////////
        // Plugin class
        cr.plugins_.Listview = function(runtime)
        {
           this.runtime = runtime;
        };
        
        (function ()
        {
           /////////////////////////////////////
           var pluginProto = cr.plugins_.Listview.prototype;
              
           /////////////////////////////////////
           // Object type class
           pluginProto.Type = function(plugin)
           {
              this.plugin = plugin;
              this.runtime = plugin.runtime;
           };
        
           var typeProto = pluginProto.Type.prototype;
        
           // called on startup for each object type
           typeProto.onCreate = function()
           {
           };
        
           /////////////////////////////////////
           // Instance class
           pluginProto.Instance = function(type)
           {
              this.type = type;
              this.runtime = type.runtime;
           };
           
           var instanceProto = pluginProto.Instance.prototype;
        
           /////////////////////////////////////
           // PlayLive vars
           var header = [];
           var lenCol = [];
           var align = "";
           var valign = "";
           
           // called whenever an instance is created
           instanceProto.onCreate = function()
           {
              // Not supported in DC
              if (this.runtime.isDomFree)
              {
                 cr.logexport("[Construct 2] List plugin not supported on this platform - the object will not be created");
                 return;
              }
           
              this.elem = document.createElement("div");
              this.elem.table = document.createElement("table");
              this.elem.id = this.properties[4];
              if($.trim(this.elem.id) <= 0)
              {
                 this.elem.id = makeid();
              }
              this.lastSelection = -1 ;
        
              $(this.elem).appendTo(this.runtime.canvasdiv ? this.runtime.canvasdiv : "body");
              
              // PlayLive
              if(this.properties[16] == 0)
                 $(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","auto").css("padding","0px").css("margin","0px");
              else if(this.properties[16] == 1)
                 $(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","scroll").css("padding","0px").css("margin","0px");
              else if(this.properties[16] == 2)
                 $(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","hidden").css("padding","0px").css("margin","0px");
              
              var self = this;
              var ligne = [];
              var theme = "";
              
              if($.trim(self.properties[0]).length>0)
              {
                 if(self.properties[0][self.properties[0].length-1] == ":")
                    self.properties[0]= self.properties[0].slice(0,-1);
                 header=self.properties[0].split(":");
              }
              
              if($.trim(self.properties[1]).length>0)
              {
                 if(self.properties[1][self.properties[1].length-1] == ";")
                    self.properties[1]= self.properties[1].slice(0,-1);
                 ligne=self.properties[1].split(";");
              }
              
              if($.trim(self.properties[2]).length>0)
              {
                 if(self.properties[2][self.properties[2].length-1] == ":")
                    self.properties[2]= self.properties[2].slice(0,-1);
                 lenCol=self.properties[2].split(":");
              }
              
              switch(self.properties[8])
              {
                 case 0 : align="left";break;
                 case 1 : align="center";break;
                 case 2 : align="right";break;
                 default : align="center";break;
              }
              switch(self.properties[9])
              {
                 case 0 : valign="top";break;
                 case 1 : valign="center";break;
                 case 2 : valign="bottom";break;
                 default : valign="center";break;
              }
              
              
              this.align = align;
              this.valign = valign;
              //$(self.elem.table).addClass("tablesorter");
              
              
              $(self.elem.table).attr({
                             "border":self.properties[10],
                             "cellpadding":"0px",
                             "cellspacing":"0px",
                             "width":"100%"
              }).css("color","black");
        
              if(header.length>0)
              {
                 $(self.elem.table).append("<thead><tr></tr></thead>");
                 for(var i=0 ; i<header.length ; i++)
                 {
                    $(this.elem.table).find("thead tr").append("<th width='"+lenCol[i]+"' colNum='"+i+"' align='"+align+"' valign='"+valign+"' >"+header[i]+"</th>");
                 }
              }
              
              $(self.elem.table).append("<tbody></tbody>");
              if(ligne.length>0)
              {
                 for(var i=0 ; i<ligne.length ; i++)
                 {
                    var rowId = "";
                    do
                    {
                       rowId = makeid();
                    }while( $("#"+rowId).length);
                    var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
                    var a = ligne[i].split(":");
                    for(var j=0 ; j<a.length ; j++)
                    {
                       if($.trim(self.properties[7]).length >0)
                          LigneToAdd.append("<td align='"+align+"' valign='"+valign+"' style='"+self.properties[7]+"'>"+a[j]+"</td>");
                       else
                          LigneToAdd.append("<td align='"+align+"' valign='"+valign+"'>"+a[j]+"</td>");
                    }
                    $(self.elem.table).find("tbody").append(LigneToAdd);
                 }
              }
        
              if($.trim(self.properties[5]).length >0)
                 $(self.elem.table).find("thead tr").attr("style",self.properties[5]);
              if($.trim(self.properties[6]).length >0)
                 $(self.elem.table).find("tbody tr").attr("style",self.properties[6]);
              
              if( self.properties[14] == 1)
              {
                 if(self.properties[15] > 0)
                 {
                    switch(self.properties[15])
                    {
                       case 0 : theme="none";break;
                       case 1 : theme="blackice";break;
                       case 2 : theme="blue";break;
                       case 3 : theme="bootstrap";break;
                       case 4 : theme="bootstrap_2";break;
                       case 5 : theme="dark";break;
                       case 6 : theme="default";break;
                       case 7 : theme="dropbox";break;
                       case 8 : theme="green";break;
                       case 9 : theme="grey";break;
                       case 10 : theme="ice";break;
                       case 11 : theme="jui";break;
                       default : theme="default";break;
                    }
                    $(self.elem.table).tablesorter(
                    {
                       theme:theme
                    });
                 }
                 else
                 {
                    $(self.elem.table).tablesorter().removeClass("tablesorter-default");
                 }
              }
              else
              {
                 if(self.properties[15] > 0)
                 {
                    switch(self.properties[15])
                    {
                       case 0 : theme="none";break;
                       case 1 : theme="blackice";break;
                       case 2 : theme="blue";break;
                       case 3 : theme="bootstrap";break;
                       case 4 : theme="bootstrap_2";break;
                       case 5 : theme="dark";break;
                       case 6 : theme="default";break;
                       case 7 : theme="dropbox";break;
                       case 8 : theme="green";break;
                       case 9 : theme="grey";break;
                       case 10 : theme="ice";break;
                       case 11 : theme="jui";break;
                       default : theme="default";break;
                    }
                    $(self.elem.table).addClass("tablesorter-"+theme);
                 }
              }
        
              // PlayLive
              if( self.properties[13] == 1)
                 $(self.elem.table).stickyTableHeaders({ scrollableArea: $(".scrollable-area-"+this.elem.id) })
        
              var sorterAlign = 2;
              var sorterVisib = "initial";
        
              switch(self.properties[12])
              {
                 case 0 : sorterAlign="left";break;
                 case 1 : sorterAlign="center";break;
                 case 2 : sorterAlign="right";break;
                 default : sorterVisib="right";break;
              }
        
              $(self.elem.table).find("thead tr .header").css(
              {
                 "background-position":"center "+sorterAlign
              });
              if( self.properties[11] == 0)
              {
                 $(self.elem.table).find("thead tr .header").css(
                 {
                    "background-image":"none"
                 });
              }
              
              
              $(this.elem.table).find("tbody").on('click' , 'tr', function() 
              {
                 if( parseInt($(this).index()) != self.lastSelection)
                 {
                    self.lastSelection = parseInt($(this).index());
                    self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnSelectionChanged, self);
                 }
              });
              
              $(this.elem.table).find("tbody").on('mouseover' , 'tr', function() 
              {
                 self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnHover, self);
              });
              
              this.elem.onclick = function(e) {
                    e.stopPropagation();
                    self.runtime.isInUserInputEvent = true;
                    self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnClicked, self);
                    self.runtime.isInUserInputEvent = false;
                 };
              
              this.elem.ondblclick = function(e) {
                    e.stopPropagation();
                    self.runtime.isInUserInputEvent = true;
                    self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnDoubleClicked, self);
                    self.runtime.isInUserInputEvent = false;
                 };
              
              // Prevent touches reaching the canvas
              this.elem.addEventListener("touchstart", function (e) {
                 e.stopPropagation();
              }, false);
              
              this.elem.addEventListener("touchmove", function (e) {
                 e.stopPropagation();
              }, false);
              
              this.elem.addEventListener("touchend", function (e) {
                 e.stopPropagation();
              }, false);
              
              // Prevent clicks being blocked
              jQuery(this.elem).mousedown(function (e) {
                 e.stopPropagation();
              });
              
              jQuery(this.elem).mouseup(function (e) {
                 e.stopPropagation();
              });
              
              this.lastLeft = 0;
              this.lastTop = 0;
              this.lastRight = 0;
              this.lastBottom = 0;
              this.lastWinWidth = 0;
              this.lastWinHeight = 0;
              this.isVisible = true;
              
              this.updatePosition(true);
              
              this.runtime.tickMe(this);
           };
           
           instanceProto.saveToJSON = function ()
           {
              var o = {
                 "tooltip": this.elem.title,
                 "disabled": !!this.elem.disabled,
                 "items": [],
                 "sel": []
              };
              
              var i, len;
              var itemsarr = o["items"];
              
              for (i = 0, len = this.elem.length; i < len; i++)
              {
                 itemsarr.push(this.elem.options[i].text);
              }
              
              var selarr = o["sel"];
              
              if (this.elem["multiple"])
              {
                 for (i = 0, len = this.elem.length; i < len; i++)
                 {
                    if (this.elem.options[i].selected)
                       selarr.push(i);
                 }
              }
              else
              {
                 selarr.push(this.elem["selectedIndex"]);
              }
              
              return o;
           };
           
           instanceProto.loadFromJSON = function (o)
           {
              this.elem.title = o["tooltip"];
              this.elem.disabled = o["disabled"];
              
              var itemsarr = o["items"];
              
              // Clear the list
              while (this.elem.length)
                 this.elem.remove(this.elem.length - 1);
                 
              var i, len, opt;
              for (i = 0, len = itemsarr.length; i < len; i++)
              {
                 opt = document.createElement("option");
                 opt.text = itemsarr[i];
                 this.elem.add(opt);
              }
              
              var selarr = o["sel"];
              
              if (this.elem["multiple"])
              {
                 for (i = 0, len = selarr.length; i < len; i++)
                 {
                    if (selarr[i] < this.elem.length)
                       this.elem.options[selarr[i]].selected = true;
                 }
              }
              else if (selarr.length >= 1)
              {
                 this.elem["selectedIndex"] = selarr[0];
              }
           };
           
           instanceProto.onDestroy = function ()
           {
              if (this.runtime.isDomFree)
                    return;
              
              jQuery(this.elem).remove();
              this.elem = null;
           };
           
           instanceProto.tick = function ()
           {
              this.updatePosition();
           };
           
           instanceProto.updatePosition = function (first)
           {
              if (this.runtime.isDomFree)
                 return;
              
              var left = this.layer.layerToCanvas(this.x, this.y, true);
              var top = this.layer.layerToCanvas(this.x, this.y, false);
              var right = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, true);
              var bottom = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, false);
              
              var rightEdge = this.runtime.width / this.runtime.devicePixelRatio;
              var bottomEdge = this.runtime.height / this.runtime.devicePixelRatio;
              
              // Is entirely offscreen or invisible: hide
              if (!this.visible || !this.layer.visible || right <= 0 || bottom <= 0 || left >= rightEdge || top >= bottomEdge)
              {
                 if (this.isVisible)
                    jQuery(this.elem).hide();
                 
                 this.isVisible = false;
                 return;
              }
              
              // Truncate to canvas size
              if (left < 1)
                 left = 1;
              if (top < 1)
                 top = 1;
              if (right >= rightEdge)
                 right = rightEdge - 1;
              if (bottom >= bottomEdge)
                 bottom = bottomEdge - 1;
              
              var curWinWidth = window.innerWidth;
              var curWinHeight = window.innerHeight;
                 
              // Avoid redundant updates
              if (!first && this.lastLeft === left && this.lastTop === top && this.lastRight === right && this.lastBottom === bottom && this.lastWinWidth === curWinWidth && this.lastWinHeight === curWinHeight)
              {
                 if (!this.isVisible)
                 {
                    jQuery(this.elem).show();
                    this.isVisible = true;
                 }
                 
                 return;
              }
                 
              this.lastLeft = left;
              this.lastTop = top;
              this.lastRight = right;
              this.lastBottom = bottom;
              this.lastWinWidth = curWinWidth;
              this.lastWinHeight = curWinHeight;
              
              if (!this.isVisible)
              {
                 jQuery(this.elem).show();
                 this.isVisible = true;
              }
              
              var offx = Math.round(left) + jQuery(this.runtime.canvas).offset().left;
              var offy = Math.round(top) + jQuery(this.runtime.canvas).offset().top;
              jQuery(this.elem).css("position", "absolute");
              jQuery(this.elem).offset({left: offx, top: offy});
              jQuery(this.elem).width(Math.round(right - left));
              jQuery(this.elem).height(Math.round(bottom - top));
              
           };
           
           // only called if a layout object
           instanceProto.draw = function(ctx)
           {
           };
           
           instanceProto.drawGL = function(glw)
           {
           };
           
           /**BEGIN-PREVIEWONLY**/
           instanceProto.getDebuggerValues = function (propsections)
           {
              propsections.push({
                 "title": "List",
                 "properties": [
                    {"name": "Item count", "value": this.elem.length, "readonly": true},
                    {"name": "Enabled", "value": !this.elem.disabled},
                    {"name": "Tooltip", "value": this.elem.title},
                    {"name": "Selected index", "value": this.elem.selectedIndex}
                 ]
              });
              
              var props = [], i, len;
              for (i = 0, len = this.elem.length; i < len; ++i)
              {
                 props.push({"name": i.toString(), "value": this.elem.options[i].text});
              }
              
              propsections.push({
                 "title": "Items",
                 "properties": props
              });
           };
           
           instanceProto.onDebugValueEdited = function (header, name, value)
           {
              if (header === "List")
              {
                 switch (name) {
                 case "Enabled":
                    this.elem.disabled = !value;
                    break;
                 case "Tooltip":
                    this.elem.title = value;
                    break;
                 case "Selected index":
                    this.elem.selectedIndex = value;
                    break;
                 }
              }
              else if (header === "Items")
              {
                 this.elem.options[parseInt(name, 10)].text = value;
              }
           };
           /**END-PREVIEWONLY**/
        
           //////////////////////////////////////
           // Conditions
           function Cnds() {};
           
           Cnds.prototype.OnSelectionChanged = function ()
           {
              return true;
           };
           
           Cnds.prototype.OnClicked = function ()
           {
              return true;
           };
           
           Cnds.prototype.OnDoubleClicked = function ()
           {
              return true;
           };
           
           Cnds.prototype.OnHover = function ()
           {
              return true;
           };
           
           
           pluginProto.cnds = new Cnds();
           
           //////////////////////////////////////
           // Actions
           function Acts() {};
           
           Acts.prototype.SelectedRow = function (i)
           {
              if (this.runtime.isDomFree)
                 return;
              
              this.lastSelection = i;
              $(this.elem.table).find("tbody tr.selected").removeClass("selected");
              $(this.elem.table).find("tbody tr").eq(i).addClass("selected");
           };
           
           Acts.prototype.SetVisible = function (vis)
           {
              if (this.runtime.isDomFree)
                 return;
              
              this.visible = (vis !== 0);
           };
           
           Acts.prototype.SetFocus = function ()
           {
              if (this.runtime.isDomFree)
                 return;
              
              this.elem.table.focus();
           };
           
           Acts.prototype.SetBlur = function ()
           {
              if (this.runtime.isDomFree)
                 return;
              
              this.elem.table.blur();
           };
        
           
           Acts.prototype.AddRow = function (text_)
           {
              if (this.runtime.isDomFree)
                 return;
        
              var rowId = "";
              do { rowId = makeid(); }
              while( $("#"+rowId).length);
              
              
              var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
              var a = text_.split(":");
              var r = a.toString().replace(/\\,/g, ":");
              a = r.split(",");
        
              for(var j=0 ; j<a.length ; j++)
              {
                 LigneToAdd.append("<td align='"+this.align+"' valign='"+this.valign+"' style='"+this.properties[7]+"'>"+a[j]+"</td>");
              }
        
              $(this.elem.table).find("tbody").append(LigneToAdd);
        
              if( this.properties[14] == 1)
              {
                 $(this.elem.table).trigger('update');     
                 $(this.elem.table).trigger("sorton",[$(this.elem.table).get(0).config.sortList]); 
              }
           };
           
           Acts.prototype.AddRowAt = function (index_, text_)
           {
              if (this.runtime.isDomFree)
                 return;
        
              var rowId = "";
              do
              {
                 rowId = makeid();
              }while( $("#"+rowId).length);
              
              
              var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
              var a = text_.split(":");
              var r = a.toString().replace(/,,/g, ":");
              a = r.split(",");
              for(var j=0 ; j<a.length ; j++)
              {
                 LigneToAdd.append("<td align='"+this.align+"' valign='"+this.valign+"' style='"+this.properties[7]+"'>"+a[j]+"</td>");
              }
              
              if(index_ > 0)
                 LigneToAdd.insertBefore($(this.elem.table).find("tbody tr").eq(index_));
              else
                 LigneToAdd.appendTo($(this.elem.table).find("tbody"));
              
              if( this.properties[14] == 1 )
              {
                 $(this.elem.table).trigger('update');
                 $(this.elem.table).trigger("sorton",[$(this.elem.table).get(0).config.sortList]); 
              }
           };
           
           Acts.prototype.RemoveAt = function (index_)
           {
              if (this.runtime.isDomFree)
                 return;
              
              if(index_ == this.lastSelection)
                    this.lastSelection = -1 ;
        
              $(this.elem.table).find("tbody tr").eq(index_).remove();
           };
        
           Acts.prototype.ChangeRowCssAt = function (index_,css)
           {
              if (this.runtime.isDomFree)
                 return;
              
              var item = $(this.elem.table).find("tbody tr").eq(index_);
              if(item.is("[style]"))
                 item.attr("style",item.attr("style")+css);
              else
                 item.attr("style",css);
           };
           
           Acts.prototype.ChangeCellCssAt = function (index_,index_2,css)
           {
              if (this.runtime.isDomFree)
                 return;
        
              var item = $(this.elem.table).find("tbody tr").eq(index_).find("td").eq(index_2);
              if(item.is("[style]"))
                 item.attr("style",item.attr("style")+css);
              else
                 item.attr("style",css);
           };
           
           Acts.prototype.StoreValueAt = function (index_,key,val)
           {
              if (this.runtime.isDomFree)
                 return;
        
              $(this.elem.table).find("tbody tr").eq(index_).attr(key,val);
           };
           
           Acts.prototype.sortColumn = function (index_,val)
           {
              if (this.runtime.isDomFree)
                 return;
              $("table").trigger("sorton",[ [[index_,val]] ]);
              
           };
           
           Acts.prototype.Clear = function ()
           {
              $(this.elem.table).find("tbody tr").remove();
           };
        
           Acts.prototype.ScrollTop = function () // PlayLive
           {
              if (this.runtime.isDomFree)
                 return;
        
                this.elem.scrollTop = 0;
           };
        
           Acts.prototype.ScrollBottom = function () // PlayLive
           {
              if (this.runtime.isDomFree)
                 return;
              
              this.elem.scrollTop = this.elem.scrollHeight;
           };
        
          Acts.prototype.ScrollRight = function () // PlayLive
           {
              if (this.runtime.isDomFree)
                 return;
        
                this.elem.scrollLeft = this.elem.scrollWidth;
           };
        
           Acts.prototype.ScrollLeft = function () // PlayLive
           {
              if (this.runtime.isDomFree)
                 return;
              
              this.elem.scrollLeft = 0;
           };
        
           Acts.prototype.SetHeader = function (str_) // PlayLive
           {
              if (this.runtime.isDomFree)
                 return;
        /*
              var newheader = str_.split(":");
        
              if (newheader.length > 0)
              {
                 $(this.elem.table).find("thead tr th").text("");
                 var table = $(this.elem.table).find("thead tr th").length / 2;
        
                 while (newheader.length > table) {
                    $(this.elem.table).find("thead tr").append("<th align='"+align+"' valign='"+valign+"'></th>");
                    table++;
                 }
        
                 while (newheader.length < table) {
                    $(this.elem.table).find("thead tr th:eq("+(table)+")").remove();
                    $(this.elem.table).find("thead tr th:eq("+(table)+")").remove();
                    table--;
                 }
        
                 for (var i = 0; i < table; i++) {
                    $(this.elem.table).find("thead tr th:eq("+i+")").text(newheader[i]);
                 }
              }
        */
              var newheader = str_.split(":");
              $(this.elem.table).find("thead tr th").text("");
        
              for (var i = 0; i < newheader.length; i++)
                 $(this.elem.table).find("thead tr th:eq("+i+")").text(newheader[i]);
        
           };
        
           Acts.prototype.ChangeValue = function (row_, cell_, str_) // PlayLive
           {
              $(this.elem.table).find("tbody tr:eq("+row_+") td:eq("+cell_+")").text(str_);
           };
           
           pluginProto.acts = new Acts();
           
           //////////////////////////////////////
           // Expressions
           function Exps() {};
           
           Exps.prototype.RowsCount = function (ret)
           {
              if (this.runtime.isDomFree)
              {
                 ret.set_int(0);
                 return;
              }
              
              ret.set_int($(this.elem.table).find("tbody tr").length);
           };
           
           Exps.prototype.SelectedRowIndex = function (ret)
           {
              if (this.runtime.isDomFree)
              {
                 ret.set_int(0);
                 return;
              }
              ret.set_int(this.lastSelection);
           };
           
           Exps.prototype.SubTextSelectedRow = function (ret,SubTextIndex)
           {
              if (this.runtime.isDomFree)
              {
                 ret.set_string("");
                 return;
              }
              
              ret.set_string($(this.elem.table).find("tbody tr").eq(this.lastSelection).find("td").eq(SubTextIndex).text());
           };
           
           
           Exps.prototype.SubTextAt = function (ret,LigneIndex , SubTextIndex)
           {
              if (this.runtime.isDomFree)
              {
                 ret.set_string("");
                 return;
              }
              
              ret.set_string($(this.elem.table).find("tbody tr").eq(LigneIndex).find("td").eq(SubTextIndex).text() );
           };
           
           
           Exps.prototype.getValueOfKeyAt = function (ret,RowIndex , Key) // PlayLive
           {
              if (this.runtime.isDomFree)
              {
                 ret.set_string("");
                 return;
              }
              
              ret.set_string($(this.elem.table).find("tbody tr").eq(RowIndex).attr(Key) );
           };
           pluginProto.exps = new Exps();
        
        }());
        
        function makeid()
        {
            var text = "";
            var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
           
            for( var i=0; i < 10; i++ )
                text += possible.charAt(Math.floor(Math.random() * possible.length));
            return text;
        }
        
        function createCSSSelector(selector, style) 
        {
           var cssrules =  $("<style type='text/css'> </style>").appendTo("head");
           cssrules.append(selector+"{ "+style+" }"); 
        }[/code:2fv33rzn]
      • CJK I never thought about it! Will be very useful, thank you!

      • ScrollRight does work perfectly, but, unfortunately, it now does not minify, and I can't figure out why ;-( Anybody can help, please?

        Thanks.

      Jump to:
      Active Users
      There are 1 visitors browsing this topic (0 users and 1 guests)