diff options
17 files changed, 505 insertions, 73 deletions
diff --git a/.gitattributes b/.gitattributes index 072669b8..80a04237 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1977,6 +1977,8 @@ tests/FunctionalTests/active-controls/protected/pages/PostLoadingTest.page -text  tests/FunctionalTests/active-controls/protected/pages/PostLoadingTest.php -text  tests/FunctionalTests/active-controls/protected/pages/RatingList.page -text  tests/FunctionalTests/active-controls/protected/pages/RatingList.php -text +tests/FunctionalTests/active-controls/protected/pages/RepeaterWithActiveControls.page -text +tests/FunctionalTests/active-controls/protected/pages/RepeaterWithActiveControls.php -text  tests/FunctionalTests/active-controls/protected/pages/ReplaceContentTest.page -text  tests/FunctionalTests/active-controls/protected/pages/ReplaceContentTest.php -text  tests/FunctionalTests/active-controls/protected/pages/TInPlaceTextBoxTest.page -text diff --git a/framework/Web/Javascripts/js/compressed/ajax.js b/framework/Web/Javascripts/js/compressed/ajax.js index 696968c7..16dacb52 100644 --- a/framework/Web/Javascripts/js/compressed/ajax.js +++ b/framework/Web/Javascripts/js/compressed/ajax.js @@ -262,12 +262,13 @@ this.time=setTimeout(this.checkChanges.bind(this),parseInt(this.options.Interval  {var request=new Prado.CallbackRequest(this.options.EventTarget,this.options);var param={'OldValue':oldValue,'NewValue':newValue};request.setCallbackParameter(param);request.dispatch();}},{timers:{},register:function(timer)  {Prado.WebUI.TValueTriggeredCallback.timers[timer.options.ID]=timer;},stop:function(id)  {Prado.WebUI.TValueTriggeredCallback.timers[id].stopObserving();}});Prado.WebUI.TInPlaceTextBox=Base.extend({isSaving:false,isEditing:false,editField:null,constructor:function(options) -{this.options=Object.extend({LoadTextFromSource:false,TextMode:'SingleLine'},options||{});this.element=$(this.options.ID);this.initializeListeners();},initializeListeners:function() +{this.options=Object.extend({LoadTextFromSource:false,TextMode:'SingleLine'},options||{});this.element=$(this.options.ID);Prado.WebUI.TInPlaceTextBox.register(this);this.initializeListeners();},initializeListeners:function()  {this.onclickListener=this.enterEditMode.bindAsEventListener(this);Event.observe(this.element,'click',this.onclickListener);if(this.options.ExternalControl)  Event.observe($(this.options.ExternalControl),'click',this.onclickListener);},enterEditMode:function(evt) -{if(this.isSaving)return;if(this.isEditing)return;this.isEditing=true;this.onEnterEditMode();this.createEditorInput();this.showTextBox();this.editField.disabled=false;if(this.options.LoadTextOnEdit) +{if(this.isSaving||this.isEditing)return;this.isEditing=true;this.onEnterEditMode();this.createEditorInput();this.showTextBox();this.editField.disabled=false;if(this.options.LoadTextOnEdit)  this.loadExternalText();Prado.Element.focus(this.editField);if(evt) -Event.stop(evt);return false;},showTextBox:function() +Event.stop(evt);return false;},exitEditMode:function(evt) +{this.isEditing=false;this.isSaving=false;this.editField.disabled=false;this.element.innerHTML=this.editField.value;this.showLabel();},showTextBox:function()  {Element.hide(this.element);Element.show(this.editField);},showLabel:function()  {Element.show(this.element);Element.hide(this.editField);},createEditorInput:function()  {if(this.editField==null) @@ -302,28 +303,39 @@ this.showLabel();}},onTextChanged:function(text)  {this.isSaving=false;this.isEditing=false;this.showLabel();},onTextChangedSuccess:function(sender,parameter)  {this.isSaving=false;this.isEditing=false;if(this.options.AutoHide)  this.showLabel();this.element.innerHTML=parameter==null?this.editField.value:parameter;this.editField.disabled=false;},onTextChangedFailure:function(sender,parameter) -{this.editField.disabled=false;this.isSaving=false;this.isEditing=false;}});Prado.WebUI.TRatingList=Base.extend({selectedIndex:-1,enabled:true,readOnly:false,constructor:function(options) -{var cap=$(options.CaptionID);this.options=Object.extend({caption:cap?cap.innerHTML:''},options||{});Prado.WebUI.TRatingList.register(this);this._init();this.selectedIndex=options.SelectedIndex;this.setRating(this.selectedIndex);},_init:function(options) +{this.editField.disabled=false;this.isSaving=false;this.isEditing=false;}},{textboxes:{},register:function(obj) +{Prado.WebUI.TInPlaceTextBox.textboxes[obj.options.TextBoxID]=obj;},setDisplayTextBox:function(id,value) +{var textbox=Prado.WebUI.TInPlaceTextBox.textboxes[id];if(textbox) +{if(value) +textbox.enterEditMode(null);else +{textbox.exitEditMode(null);}}}});Prado.WebUI.TRatingList=Base.extend({selectedIndex:-1,rating:-1,enabled:true,readOnly:false,constructor:function(options) +{var cap=$(options.CaptionID);this.options=Object.extend({caption:cap?cap.innerHTML:''},options||{});Prado.WebUI.TRatingList.register(this);this._init();this.selectedIndex=options.SelectedIndex;this.rating=options.Rating;if(options.Rating<=0&&options.SelectedIndex>=0) +this.rating=options.SelectedIndex+1;this.showRating(this.rating);},_init:function(options)  {Element.addClassName($(this.options.ListID),this.options.Style);this.radios=new Array();var index=0;for(var i=0;i<this.options.ItemCount;i++)  {var radio=$(this.options.ListID+'_c'+i);var td=radio.parentNode;if(radio&&td.tagName.toLowerCase()=='td')  {this.radios.push(radio);Event.observe(td,"mouseover",this.hover.bindEvent(this,index));Event.observe(td,"mouseout",this.recover.bindEvent(this,index));Event.observe(td,"click",this.click.bindEvent(this,index));index++;Element.addClassName(td,"rating");}}},hover:function(ev,index)  {if(this.enabled==false)return;for(var i=0;i<this.radios.length;i++) -{var action=i<=index?'addClassName':'removeClassName' -Element[action](this.radios[i].parentNode,"rating_selected");} -this.setCaption(index);},recover:function(ev,index) -{if(this.enabled==false)return;for(var i=0;i<=index;i++) -Element.removeClassName(this.radios[i].parentNode,"rating_selected");this.setRating(this.selectedIndex);},click:function(ev,index) +{var node=this.radios[i].parentNode;var action=i<=index?'addClassName':'removeClassName' +Element[action](node,"rating_hover");Element.removeClassName(node,"rating_selected");Element.removeClassName(node,"rating_half");} +this.showCaption(this.getIndexCaption(index));},recover:function(ev,index) +{if(this.enabled==false)return;this.showRating(this.rating);this.showCaption(this.options.caption);},click:function(ev,index)  {if(this.enabled==false)return;for(var i=0;i<this.radios.length;i++) -this.radios[i].checked=(i==index);this.selectedIndex=index;this.setRating(index);var requestOptions=Object.extend({ID:this.options.ListID+"_c"+index,EventTarget:this.options.ListID+"$c"+index},this.options);var request=new Prado.CallbackRequest(requestOptions.EventTarget,requestOptions);if(request.dispatch()==false) -Event.stop(ev);},setRating:function(index) -{for(var i=0;i<this.radios.length;i++) -{var node=this.radios[i].parentNode;var action=i>index?'removeClassName':'addClassName' -Element[action](this.radios[i].parentNode,"rating_selected");} -this.setCaption(index);},setCaption:function(index) -{var value=index>-1?this.radios[index].value:this.options.caption;var caption=$(this.options.CaptionID);if(caption)caption.innerHTML=value;$(this.options.ListID).title=value;},setEnabled:function(value) +this.radios[i].checked=(i==index);this.selectedIndex=index;this.setRating(index+1);this.dispatchRequest(ev);},dispatchRequest:function(ev) +{var requestOptions=Object.extend({ID:this.options.ListID+"_c"+this.selectedIndex,EventTarget:this.options.ListName+"$c"+this.selectedIndex},this.options);var request=new Prado.CallbackRequest(requestOptions.EventTarget,requestOptions);if(request.dispatch()==false) +Event.stop(ev);},setRating:function(value) +{this.rating=value;var base=Math.floor(value-1);var remainder=value-base-1;var halfMax=this.options.HalfRating["1"];var index=remainder>halfMax?base+1:base;for(var i=0;i<this.radios.length;i++) +this.radios[i].checked=(i==index);var caption=this.getIndexCaption(index);this.setCaption(caption);this.showCaption(caption);this.showRating(value);},showRating:function(value) +{var base=Math.floor(value-1);var remainder=value-base-1;var halfMin=this.options.HalfRating["0"];var halfMax=this.options.HalfRating["1"];var index=remainder>halfMax?base+1:base;var hasHalf=remainder>=halfMin&&remainder<=halfMax;for(var i=0;i<this.radios.length;i++) +{var node=this.radios[i].parentNode;var action=i>index?'removeClassName':'addClassName';Element[action](node,"rating_selected");if(i==index+1&&hasHalf) +Element.addClassName(node,"rating_half");else +Element.removeClassName(node,"rating_half");Element.removeClassName(node,"rating_hover");}},getIndexCaption:function(index) +{return index>-1?this.radios[index].value:this.options.caption;},showCaption:function(value) +{var caption=$(this.options.CaptionID);if(caption)caption.innerHTML=value;$(this.options.ListID).title=value;},setCaption:function(value) +{this.options.caption=value;this.showCaption(value);},setEnabled:function(value)  {this.enabled=value;for(var i=0;i<this.radios.length;i++)  {var action=value?'removeClassName':'addClassName'  Element[action](this.radios[i].parentNode,"rating_disabled");}}},{ratings:{},register:function(rating)  {Prado.WebUI.TRatingList.ratings[rating.options.ListID]=rating;},setEnabled:function(id,value)  {Prado.WebUI.TRatingList.ratings[id].setEnabled(value);},setRating:function(id,value) -{Prado.WebUI.TRatingList.ratings[id].setRating(value);Prado.WebUI.TRatingList.ratings[id].selectedIndex=value;}});
\ No newline at end of file +{Prado.WebUI.TRatingList.ratings[id].setRating(value);},setCaption:function(id,value) +{Prado.WebUI.TRatingList.ratings[id].setCaption(value);}});
\ No newline at end of file diff --git a/framework/Web/Javascripts/js/debug/ajax.js b/framework/Web/Javascripts/js/debug/ajax.js index ba777546..8b75c2ad 100644 --- a/framework/Web/Javascripts/js/debug/ajax.js +++ b/framework/Web/Javascripts/js/debug/ajax.js @@ -2396,7 +2396,7 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(  		}, options || {});
  		this.element = $(this.options.ID);
 -
 +		Prado.WebUI.TInPlaceTextBox.register(this);
  		this.initializeListeners();
  	},
 @@ -2417,8 +2417,7 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(  	 */
  	enterEditMode :  function(evt)
  	{
 -	    if (this.isSaving) return;
 -	    if (this.isEditing) return;
 +	    if (this.isSaving || this.isEditing) return;
  	    this.isEditing = true;
  		this.onEnterEditMode();
  		this.createEditorInput();
 @@ -2432,6 +2431,15 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(      	return false;
  	},
 +	exitEditMode : function(evt)
 +	{
 +		this.isEditing = false;
 +		this.isSaving = false;
 +		this.editField.disabled = false;
 +		this.element.innerHTML = this.editField.value;
 +		this.showLabel();
 +	},
 +
  	showTextBox : function()
  	{
  		Element.hide(this.element);
 @@ -2608,11 +2616,34 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(  		this.isSaving = false;
  		this.isEditing = false;
  	}
 +},
 +{
 +	textboxes : {},
 +
 +	register : function(obj)
 +	{
 +		Prado.WebUI.TInPlaceTextBox.textboxes[obj.options.TextBoxID] = obj;
 +	},
 +
 +	setDisplayTextBox : function(id,value)
 +	{
 +		var textbox = Prado.WebUI.TInPlaceTextBox.textboxes[id];
 +		if(textbox)
 +		{
 +			if(value)
 +				textbox.enterEditMode(null);
 +			else
 +			{
 +				textbox.exitEditMode(null);
 +			}
 +		}
 +	}
  });  Prado.WebUI.TRatingList = Base.extend(
  {
  	selectedIndex : -1,
 +	rating: -1,
  	enabled : true,
  	readOnly : false,
 @@ -2627,7 +2658,10 @@ Prado.WebUI.TRatingList = Base.extend(  		Prado.WebUI.TRatingList.register(this);
  		this._init();
  		this.selectedIndex = options.SelectedIndex;
 -		this.setRating(this.selectedIndex);
 +		this.rating = options.Rating;
 +		if(options.Rating <= 0 && options.SelectedIndex >= 0)
 +			this.rating = options.SelectedIndex+1;
 +		this.showRating(this.rating);
  	},
  	_init: function(options)
 @@ -2656,18 +2690,20 @@ Prado.WebUI.TRatingList = Base.extend(  		if(this.enabled==false) return;
  		for(var i = 0; i<this.radios.length; i++)
  		{
 +			var node = this.radios[i].parentNode;
  			var action = i <= index ? 'addClassName' : 'removeClassName'
 -			Element[action](this.radios[i].parentNode,"rating_selected");
 +			Element[action](node,"rating_hover");
 +			Element.removeClassName(node,"rating_selected");
 +			Element.removeClassName(node,"rating_half");
  		}
 -		this.setCaption(index);
 +		this.showCaption(this.getIndexCaption(index));
  	},
  	recover : function(ev,index)
  	{
  		if(this.enabled==false) return;
 -		for(var i = 0; i<=index; i++)
 -			Element.removeClassName(this.radios[i].parentNode, "rating_selected");
 -		this.setRating(this.selectedIndex);
 +		this.showRating(this.rating);
 +		this.showCaption(this.options.caption);
  	},
  	click : function(ev, index)
 @@ -2675,38 +2711,81 @@ Prado.WebUI.TRatingList = Base.extend(  		if(this.enabled==false) return;
  		for(var i = 0; i<this.radios.length; i++)
  			this.radios[i].checked = (i == index);
 +
  		this.selectedIndex = index;
 -		this.setRating(index);
 +		this.setRating(index+1);
 +
 +		this.dispatchRequest(ev);
 +	},
 +
 +	dispatchRequest : function(ev)
 +	{
  		var requestOptions = Object.extend(
  		{
 -			ID : this.options.ListID+"_c"+index,
 -			EventTarget : this.options.ListID+"$c"+index
 +			ID : this.options.ListID+"_c"+this.selectedIndex,
 +			EventTarget : this.options.ListName+"$c"+this.selectedIndex
  		},this.options);
  		var request = new Prado.CallbackRequest(requestOptions.EventTarget, requestOptions);
  		if(request.dispatch()==false)
  			Event.stop(ev);
  	},
 -	setRating: function(index)
 +	setRating : function(value)
  	{
 +		this.rating = value;
 +		var base = Math.floor(value-1);
 +		var remainder = value - base-1;
 +		var halfMax = this.options.HalfRating["1"];
 +		var index = remainder > halfMax ? base+1 : base;
 +		for(var i = 0; i<this.radios.length; i++)
 +			this.radios[i].checked = (i == index);
 +
 +		var caption = this.getIndexCaption(index);
 +		this.setCaption(caption);
 +		this.showCaption(caption);
 +		this.showRating(value);
 +	},
 +
 +	showRating: function(value)
 +	{
 +		var base = Math.floor(value-1);
 +		var remainder = value - base-1;
 +		var halfMin = this.options.HalfRating["0"];
 +		var halfMax = this.options.HalfRating["1"];
 +		var index = remainder > halfMax ? base+1 : base;
 +		var hasHalf = remainder >= halfMin && remainder <= halfMax;
  		for(var i = 0; i<this.radios.length; i++)
  		{
  			var node = this.radios[i].parentNode;
 -			var action = i > index ? 'removeClassName' : 'addClassName'
 -			Element[action](this.radios[i].parentNode, "rating_selected");
 +			var action = i > index ? 'removeClassName' : 'addClassName';
 +			Element[action](node, "rating_selected");
 +			if(i==index+1 && hasHalf)
 +				Element.addClassName(node, "rating_half");
 +			else
 +				Element.removeClassName(node, "rating_half");
 +			Element.removeClassName(node,"rating_hover");
  		}
 -		this.setCaption(index);
  	},
 -	setCaption : function(index)
 +	getIndexCaption : function(index)
 +	{
 +		return index > -1 ? this.radios[index].value : this.options.caption;
 +	},
 +
 +	showCaption : function(value)
  	{
 -		var value = index > -1 ? this.radios[index].value : this.options.caption;
  		var caption = $(this.options.CaptionID);
  		if(caption) caption.innerHTML = value;
  		$(this.options.ListID).title = value;
  	},
 +	setCaption : function(value)
 +	{
 +		this.options.caption = value;
 +		this.showCaption(value);
 +	},
 +
  	setEnabled : function(value)
  	{
  		this.enabled = value;
 @@ -2732,7 +2811,11 @@ setEnabled : function(id,value)  setRating : function(id,value)
  {
  	Prado.WebUI.TRatingList.ratings[id].setRating(value);
 -	Prado.WebUI.TRatingList.ratings[id].selectedIndex = value;
 +},
 +
 +setCaption : function(id,value)
 +{
 +	Prado.WebUI.TRatingList.ratings[id].setCaption(value);
  }
  }); diff --git a/framework/Web/Javascripts/prado/inlineeditor.js b/framework/Web/Javascripts/prado/inlineeditor.js index 14f4b73c..719c525d 100644 --- a/framework/Web/Javascripts/prado/inlineeditor.js +++ b/framework/Web/Javascripts/prado/inlineeditor.js @@ -13,7 +13,7 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(  		}, options || {});
  		this.element = $(this.options.ID);
 -
 +		Prado.WebUI.TInPlaceTextBox.register(this);
  		this.initializeListeners();
  	},
 @@ -34,8 +34,7 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(  	 */
  	enterEditMode :  function(evt)
  	{
 -	    if (this.isSaving) return;
 -	    if (this.isEditing) return;
 +	    if (this.isSaving || this.isEditing) return;
  	    this.isEditing = true;
  		this.onEnterEditMode();
  		this.createEditorInput();
 @@ -49,6 +48,15 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(      	return false;
  	},
 +	exitEditMode : function(evt)
 +	{
 +		this.isEditing = false;
 +		this.isSaving = false;
 +		this.editField.disabled = false;
 +		this.element.innerHTML = this.editField.value;
 +		this.showLabel();
 +	},
 +
  	showTextBox : function()
  	{
  		Element.hide(this.element);
 @@ -225,4 +233,26 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(  		this.isSaving = false;
  		this.isEditing = false;
  	}
 +},
 +{
 +	textboxes : {},
 +
 +	register : function(obj)
 +	{
 +		Prado.WebUI.TInPlaceTextBox.textboxes[obj.options.TextBoxID] = obj;
 +	},
 +
 +	setDisplayTextBox : function(id,value)
 +	{
 +		var textbox = Prado.WebUI.TInPlaceTextBox.textboxes[id];
 +		if(textbox)
 +		{
 +			if(value)
 +				textbox.enterEditMode(null);
 +			else
 +			{
 +				textbox.exitEditMode(null);
 +			}
 +		}
 +	}
  });
\ No newline at end of file diff --git a/framework/Web/Javascripts/ratings/blocks.css b/framework/Web/Javascripts/ratings/blocks.css index 5d13a859..b05d9eb6 100644 --- a/framework/Web/Javascripts/ratings/blocks.css +++ b/framework/Web/Javascripts/ratings/blocks.css @@ -26,7 +26,17 @@  	background-position: 1px -100px;
  }
 +.TRatingList_blocks td.rating_half
 +{
 +	background-position: 1px -200px;
 +}
 +
 +.TRatingList_blocks td.rating_hover
 +{
 +	background-position: 1px -300px;
 +}
 +
  .TRatingList_blocks td.rating_disabled
  {
  	cursor: default !important;
 -}
\ No newline at end of file +}
 diff --git a/framework/Web/Javascripts/ratings/blocks.png b/framework/Web/Javascripts/ratings/blocks.png Binary files differindex 0da75b19..93a5333e 100644 --- a/framework/Web/Javascripts/ratings/blocks.png +++ b/framework/Web/Javascripts/ratings/blocks.png diff --git a/framework/Web/Javascripts/ratings/blocks_combined.gif b/framework/Web/Javascripts/ratings/blocks_combined.gif Binary files differindex 04e8f7b8..dfe9da8d 100644 --- a/framework/Web/Javascripts/ratings/blocks_combined.gif +++ b/framework/Web/Javascripts/ratings/blocks_combined.gif diff --git a/framework/Web/Javascripts/ratings/default.css b/framework/Web/Javascripts/ratings/default.css index aa7913bf..d404f843 100644 --- a/framework/Web/Javascripts/ratings/default.css +++ b/framework/Web/Javascripts/ratings/default.css @@ -27,6 +27,16 @@  	background-position: 0px -100px;
  }
 +.TRatingList_default td.rating_half
 +{
 +	background-position: 0px -200px;
 +}
 +
 +.TRatingList_default td.rating_hover
 +{
 +	background-position: 0px -300px;
 +}
 +
  .TRatingList_default td.rating_disabled
  {
  	cursor: default !important;
 diff --git a/framework/Web/Javascripts/ratings/default.png b/framework/Web/Javascripts/ratings/default.png Binary files differindex 17bc39a1..a3148ff4 100644 --- a/framework/Web/Javascripts/ratings/default.png +++ b/framework/Web/Javascripts/ratings/default.png diff --git a/framework/Web/Javascripts/ratings/default_combined.gif b/framework/Web/Javascripts/ratings/default_combined.gif Binary files differindex fe02b446..ddab2e8b 100644 --- a/framework/Web/Javascripts/ratings/default_combined.gif +++ b/framework/Web/Javascripts/ratings/default_combined.gif diff --git a/framework/Web/Javascripts/ratings/ratings.js b/framework/Web/Javascripts/ratings/ratings.js index 9299d8d8..c8b19511 100644 --- a/framework/Web/Javascripts/ratings/ratings.js +++ b/framework/Web/Javascripts/ratings/ratings.js @@ -1,6 +1,7 @@  Prado.WebUI.TRatingList = Base.extend(
  {
  	selectedIndex : -1,
 +	rating: -1,
  	enabled : true,
  	readOnly : false,
 @@ -15,7 +16,10 @@ Prado.WebUI.TRatingList = Base.extend(  		Prado.WebUI.TRatingList.register(this);
  		this._init();
  		this.selectedIndex = options.SelectedIndex;
 -		this.setRating(this.selectedIndex);
 +		this.rating = options.Rating;
 +		if(options.Rating <= 0 && options.SelectedIndex >= 0)
 +			this.rating = options.SelectedIndex+1;
 +		this.showRating(this.rating);
  	},
  	_init: function(options)
 @@ -44,18 +48,20 @@ Prado.WebUI.TRatingList = Base.extend(  		if(this.enabled==false) return;
  		for(var i = 0; i<this.radios.length; i++)
  		{
 +			var node = this.radios[i].parentNode;
  			var action = i <= index ? 'addClassName' : 'removeClassName'
 -			Element[action](this.radios[i].parentNode,"rating_selected");
 +			Element[action](node,"rating_hover");
 +			Element.removeClassName(node,"rating_selected");
 +			Element.removeClassName(node,"rating_half");
  		}
 -		this.setCaption(index);
 +		this.showCaption(this.getIndexCaption(index));
  	},
  	recover : function(ev,index)
  	{
  		if(this.enabled==false) return;
 -		for(var i = 0; i<=index; i++)
 -			Element.removeClassName(this.radios[i].parentNode, "rating_selected");
 -		this.setRating(this.selectedIndex);
 +		this.showRating(this.rating);
 +		this.showCaption(this.options.caption);
  	},
  	click : function(ev, index)
 @@ -63,38 +69,81 @@ Prado.WebUI.TRatingList = Base.extend(  		if(this.enabled==false) return;
  		for(var i = 0; i<this.radios.length; i++)
  			this.radios[i].checked = (i == index);
 +
  		this.selectedIndex = index;
 -		this.setRating(index);
 +		this.setRating(index+1);
 +
 +		this.dispatchRequest(ev);
 +	},
 +
 +	dispatchRequest : function(ev)
 +	{
  		var requestOptions = Object.extend(
  		{
 -			ID : this.options.ListID+"_c"+index,
 -			EventTarget : this.options.ListID+"$c"+index
 +			ID : this.options.ListID+"_c"+this.selectedIndex,
 +			EventTarget : this.options.ListName+"$c"+this.selectedIndex
  		},this.options);
  		var request = new Prado.CallbackRequest(requestOptions.EventTarget, requestOptions);
  		if(request.dispatch()==false)
  			Event.stop(ev);
  	},
 -	setRating: function(index)
 +	setRating : function(value)
  	{
 +		this.rating = value;
 +		var base = Math.floor(value-1);
 +		var remainder = value - base-1;
 +		var halfMax = this.options.HalfRating["1"];
 +		var index = remainder > halfMax ? base+1 : base;
 +		for(var i = 0; i<this.radios.length; i++)
 +			this.radios[i].checked = (i == index);
 +
 +		var caption = this.getIndexCaption(index);
 +		this.setCaption(caption);
 +		this.showCaption(caption);
 +
 +		this.showRating(value);
 +	},
 +	showRating: function(value)
 +	{
 +		var base = Math.floor(value-1);
 +		var remainder = value - base-1;
 +		var halfMin = this.options.HalfRating["0"];
 +		var halfMax = this.options.HalfRating["1"];
 +		var index = remainder > halfMax ? base+1 : base;
 +		var hasHalf = remainder >= halfMin && remainder <= halfMax;
  		for(var i = 0; i<this.radios.length; i++)
  		{
  			var node = this.radios[i].parentNode;
 -			var action = i > index ? 'removeClassName' : 'addClassName'
 -			Element[action](this.radios[i].parentNode, "rating_selected");
 +			var action = i > index ? 'removeClassName' : 'addClassName';
 +			Element[action](node, "rating_selected");
 +			if(i==index+1 && hasHalf)
 +				Element.addClassName(node, "rating_half");
 +			else
 +				Element.removeClassName(node, "rating_half");
 +			Element.removeClassName(node,"rating_hover");
  		}
 -		this.setCaption(index);
  	},
 -	setCaption : function(index)
 +	getIndexCaption : function(index)
 +	{
 +		return index > -1 ? this.radios[index].value : this.options.caption;
 +	},
 +
 +	showCaption : function(value)
  	{
 -		var value = index > -1 ? this.radios[index].value : this.options.caption;
  		var caption = $(this.options.CaptionID);
  		if(caption) caption.innerHTML = value;
  		$(this.options.ListID).title = value;
  	},
 +	setCaption : function(value)
 +	{
 +		this.options.caption = value;
 +		this.showCaption(value);
 +	},
 +
  	setEnabled : function(value)
  	{
  		this.enabled = value;
 @@ -120,6 +169,10 @@ setEnabled : function(id,value)  setRating : function(id,value)
  {
  	Prado.WebUI.TRatingList.ratings[id].setRating(value);
 -	Prado.WebUI.TRatingList.ratings[id].selectedIndex = value;
 +},
 +
 +setCaption : function(id,value)
 +{
 +	Prado.WebUI.TRatingList.ratings[id].setCaption(value);
  }
  });
\ No newline at end of file diff --git a/framework/Web/UI/ActiveControls/TActiveRatingList.php b/framework/Web/UI/ActiveControls/TActiveRatingList.php index ec8eee46..c8ed524f 100644 --- a/framework/Web/UI/ActiveControls/TActiveRatingList.php +++ b/framework/Web/UI/ActiveControls/TActiveRatingList.php @@ -66,19 +66,38 @@ class TActiveRatingList extends TActiveRadioButtonList  	}
  	/**
 -	 * @return float rating value for read-only display.
 +	 * @return float rating value.
  	 */
  	public function getRating()
  	{
 -		return $this->getViewState('Rating',0);
 +		return $this->getViewState('Rating',0.0);
  	}
  	/**
 -	 * @param float rating value for read-only display.
 +	 * @param float rating value, also sets the selected Index
  	 */
  	public function setRating($value)
  	{
 -		$this->setViewState('Rating', TPropertyValue::ensureFloat($value),0);
 +		$rating = TPropertyValue::ensureFloat($value);
 +		$this->setViewState('Rating', $rating);
 +		$canUpdate = $this->getActiveControl()->getEnableUpdate();
 +		$this->getActiveControl()->setEnableUpdate(false);
 +		parent::setSelectedIndex($this->getRatingIndex($rating));
 +		$this->getActiveControl()->setEnableUpdate($canUpdate);
 +		if($this->getActiveControl()->canUpdateClientSide())
 +			$this->callClientFunction('setRating',$rating);
 +	}
 +
 +	/**
 +	 * @param float rating value
 +	 * @return int rating as integer
 +	 */
 +	protected function getRatingIndex($rating)
 +	{
 +		$interval = $this->getHalfRatingInterval();
 +		$base = intval($rating)-1;
 +		$remainder = $rating-$base-1;
 +		return $remainder > $interval[1] ? $base+1 : $base;
  	}
  	/**
 @@ -86,12 +105,13 @@ class TActiveRatingList extends TActiveRadioButtonList  	 */
  	public function setSelectedIndex($value)
  	{
 +		$value = TPropertyValue::ensureInteger($value);
  		$canUpdate = $this->getActiveControl()->getEnableUpdate();
  		$this->getActiveControl()->setEnableUpdate(false);
  		parent::setSelectedIndex($value);
  		$this->getActiveControl()->setEnableUpdate($canUpdate);
  		if($this->getActiveControl()->canUpdateClientSide())
 -			$this->callClientFunction('setRating',$value);
 +			$this->callClientFunction('setRating',$value+1);
  	}
  	/**
 @@ -122,11 +142,35 @@ class TActiveRatingList extends TActiveRadioButtonList  		$this->setViewState('CaptionID', $value, '');
  	}
 +	protected function getCaptionControl()
 +	{
 +		if(($id=$this->getCaptionID())!=='')
 +		{
 +			if($control=$this->getParent()->findControl($id))
 +				return $control;
 +		}
 +		throw new TInvalidDataValueException(
 +			'ratinglist_invalid_caption_id',$id,$this->getID());
 +	}
 +
 +	public function setCaption($value)
 +	{
 +		$this->getCaptionControl()->setText($value);
 +		if($this->getActiveControl()->canUpdateClientSide())
 +			$this->callClientFunction('setCaption',$value);
 +	}
 +
 +	public function getCaption()
 +	{
 +		return $this->getCaptionControl()->getText();
 +	}
 +
  	/**
  	 * @param boolean true to enable the rating to be changed.
  	 */
  	public function setEnabled($value)
  	{
 +		$value = TPropertyValue::ensureBoolean($value);
  		parent::setEnabled($value);
  		if($this->getActiveControl()->canUpdateClientSide())
  			$this->callClientFunction('setEnabled',$value);
 @@ -182,8 +226,10 @@ class TActiveRatingList extends TActiveRadioButtonList  	{
  		$options = parent::getPostBackOptions();
  		$options['Style'] = $this->getRatingStyleCssClass();
 -		$options['CaptionID'] = $this->getCaptionControl();
 +		$options['CaptionID'] = $this->getCaptionControlID();
  		$options['SelectedIndex'] = $this->getSelectedIndex();
 +		$options['Rating'] = $this->getRating();
 +		$options['HalfRating'] = $this->getHalfRatingInterval();
  		return $options;
  	}
 @@ -200,7 +246,7 @@ class TActiveRatingList extends TActiveRadioButtonList  	/**
  	 * @return string find the client ID of the caption control.
  	 */
 -	protected function getCaptionControl()
 +	protected function getCaptionControlID()
  	{
  		if(($id=$this->getCaptionID())!=='')
  		{
 @@ -326,4 +372,4 @@ class TActiveRatingList extends TActiveRadioButtonList  	}
  }
 -?>
\ No newline at end of file +?>
 diff --git a/framework/Web/UI/ActiveControls/TInPlaceTextBox.php b/framework/Web/UI/ActiveControls/TInPlaceTextBox.php index 236e43d5..16ffafb7 100644 --- a/framework/Web/UI/ActiveControls/TInPlaceTextBox.php +++ b/framework/Web/UI/ActiveControls/TInPlaceTextBox.php @@ -67,6 +67,37 @@ class TInPlaceTextBox extends TActiveTextBox  	}
  	/**
 +	 * @param boolean true to display the edit textbox
 +	 */
 +	public function setDisplayTextBox($value)
 +	{
 +		$value = TPropertyValue::ensureBoolean($value);
 +		$this->setViewState('DisplayTextBox', $value,false);
 +		if($this->getActiveControl()->canUpdateClientSide())
 +			$this->callClientFunction('setDisplayTextBox',$value);
 +	}
 +
 +	/**
 +	 * @return boolean true to display the edit textbox
 +	 */
 +	public function getDisplayTextBox()
 +	{
 +		return $this->getViewState('DisplayTextBox', false);
 +	}
 +
 +	/**
 +	 * Calls the client-side static method for this control class.
 +	 * @param string static method name
 +	 * @param mixed method parmaeter
 +	 */
 +	protected function callClientFunction($func,$value)
 +	{
 +		$client = $this->getPage()->getCallbackClient();
 +		$code = $this->getClientClassName().'.'.$func;
 +		$client->callClientFunction($code,array($this,$value));
 +	}
 +
 +	/**
  	 * @param string ID of the control that can trigger to edit the textbox
  	 */
  	public function setEditTriggerControlID($value)
 diff --git a/tests/FunctionalTests/active-controls/protected/pages/RatingList.page b/tests/FunctionalTests/active-controls/protected/pages/RatingList.page index a615363b..f9be4aee 100644 --- a/tests/FunctionalTests/active-controls/protected/pages/RatingList.page +++ b/tests/FunctionalTests/active-controls/protected/pages/RatingList.page @@ -15,13 +15,41 @@  	{
  		background-position: 10px -90px;
  	}
 +	.more td.rating_hover
 +	{
 +		background-position: 10px -290px;
 +	}
  </style>
 +
  <com:TLabel ID="label1" Text="Rate It:" />
 -<com:TActiveRatingList ID="list1" CaptionID="label1" RatingStyle="blocks" OnCallback="list1_oncallback">
 +<com:TActiveRatingList ID="list1"
 +	Rating="3.7"
 +	CaptionID="label1" OnCallback="list1_oncallback">
 +	<com:TListItem Text="1 Star" />
 +	<com:TListItem Text="2 Stars" />
 +	<com:TListItem Text="3 Stars" />
 +	<com:TListItem Text="4 Stars" />
 +	<com:TListItem Text="5 Stars" />
 +	<prop:ClientSide
 +		OnLoading="Element.show('status')"
 +		OnComplete="Element.hide('status')" />
 +</com:TActiveRatingList>
 +
 +<hr />
 +
 +<com:TActiveButton ID="button1" Text="Enable" OnClick="button1_clicked" />
 +<com:TActiveButton ID="button2" Text="Disable" OnClick="button2_clicked" />
 +<com:TActiveButton ID="button5" Text="Index=3" OnClick="button5_clicked" />
 +
 +
 +<hr />
 +
 +<com:TLabel ID="label2" Text="Rate It:" />
 +<com:TActiveRatingList ID="list2" CaptionID="label2" RatingStyle="blocks" OnCallback="list2_oncallback">
  	<com:TListItem Text="1 Block" />
  	<com:TListItem Text="2 Blocks" />
  	<com:TListItem Text="3 Blocks" />
 -	<com:TListItem Text="4 Blocks" />
 +	<com:TListItem Text="4 Blocks" Selected="true" />
  	<com:TListItem Text="5 Blocks" />
  	<prop:ClientSide
  		OnLoading="Element.show('status')"
 @@ -30,7 +58,7 @@  <br />
 -<com:TActiveRatingList ID="list2" Rating="3.5"
 +<com:TActiveRatingList ID="list3" Rating="3.5"
  	Attributes.title="3.5 Blocks"  RatingStyle="blocks" ReadOnly="true">
  	<com:TListItem Text="1 Block" />
  	<com:TListItem Text="2 Blocks" />
 @@ -58,7 +86,7 @@  </com:TActiveRatingList>
  <br />
 -<com:TActiveRatingList ID="list3" Rating="3.5" Attributes.title="3.5 Stars" ReadOnly="true">
 +<com:TActiveRatingList ID="list4" Rating="3.5" Attributes.title="3.5 Stars" ReadOnly="true">
  	<com:TListItem Text="1 Star" />
  	<com:TListItem Text="2 Stars" />
  	<com:TListItem Text="3 Stars" />
 @@ -76,10 +104,6 @@  		Loading...
  	</div>
 -<com:TActiveButton ID="button1" Text="Enable" OnClick="button1_clicked" />
 -<com:TActiveButton ID="button2" Text="Disable" OnClick="button2_clicked" />
 -<com:TActiveButton ID="button5" Text="Index=3" OnClick="button5_clicked" />
 -
  <com:TJavascriptLogger />
  </com:TForm>
\ No newline at end of file diff --git a/tests/FunctionalTests/active-controls/protected/pages/RatingList.php b/tests/FunctionalTests/active-controls/protected/pages/RatingList.php index c6661182..98b62e04 100644 --- a/tests/FunctionalTests/active-controls/protected/pages/RatingList.php +++ b/tests/FunctionalTests/active-controls/protected/pages/RatingList.php @@ -4,6 +4,15 @@ class RatingList extends TPage  {
  	function list1_oncallback($sender, $param)
  	{
 +		$newRating = ($sender->Rating + $sender->SelectedIndex+1)/2;
 +		$sender->Rating = $newRating;
 +		$sender->Caption = "Rating : ".$newRating;
 +		$sender->Enabled=false;
 +	}
 +
 +
 +	function list2_oncallback($sender, $param)
 +	{
  	}
  	function button1_clicked($sender, $param)
 diff --git a/tests/FunctionalTests/active-controls/protected/pages/RepeaterWithActiveControls.page b/tests/FunctionalTests/active-controls/protected/pages/RepeaterWithActiveControls.page new file mode 100644 index 00000000..5847371f --- /dev/null +++ b/tests/FunctionalTests/active-controls/protected/pages/RepeaterWithActiveControls.page @@ -0,0 +1,61 @@ +<com:TForm>
 +<style>
 +	.textbox
 +	{
 +		font-family: Arial, Helvetica, sans-serif;
 +		font-size: 1.2em;
 +		display: block;
 +		width: 20em;
 +	}
 +
 +	.textbox
 +	{
 +		padding: 2px 0px 4px 2px;
 +		border:1px solid #eee;
 +	}
 +
 +
 +	input.textbox
 +	{
 +		background-color: #ffc;
 +	}
 +	.loader
 +	{
 +		 position:absolute;
 +		 right:0px;
 +		 top:0px;
 +		 color:white;
 +		 background-color:#900;
 +		 padding: 0.5em 1em;
 +	}
 +	input.required
 +	{
 +		border: 1px solid red;
 +		background-color: pink;
 +	}
 +</style>
 +
 +<h1>Repeater With Active Controls Tests</h1>
 +
 +<com:TRepeater ID="repeater1">
 +<prop:ItemTemplate>
 +	<com:TInplaceTextBox
 +		id="edit_box"
 +		Text=<%# $this->DataItem %>
 +		OnTextChanged="Page.label_changed"
 +		AutoHideTextBox="false"
 +		CssClass="textbox" />
 +	<com:TRequiredFieldValidator ControlToValidate="edit_box" ControlCssClass="required"/>
 +</prop:ItemTemplate>
 +</com:TRepeater>
 +
 +<br />
 +
 +<com:TActiveButton id="edit_button" Text="Display As textboxes" OnCallback="enable_edit"/>
 +<com:TActiveButton id="update_button" Text="Display As Labels" Enabled="false" OnCallback="disable_edit"/>
 +
 +<com:TActiveLabel ID="label1" />
 +
 +<com:TJavascriptLogger />
 +
 +</com:TForm>
\ No newline at end of file diff --git a/tests/FunctionalTests/active-controls/protected/pages/RepeaterWithActiveControls.php b/tests/FunctionalTests/active-controls/protected/pages/RepeaterWithActiveControls.php new file mode 100644 index 00000000..c5235dc6 --- /dev/null +++ b/tests/FunctionalTests/active-controls/protected/pages/RepeaterWithActiveControls.php @@ -0,0 +1,61 @@ +<?php
 +
 +class RepeaterWithActiveControls extends TPage
 +{
 +	private $_data=array('Hello', 'World', 'Prado');
 +
 +	private $_status='';
 +
 +	public function onLoad($param)
 +	{
 +		parent::onLoad($param);
 +		if(!$this->IsCallback)
 +		{
 +			$this->repeater1->DataSource = $this->_data;
 +			$this->repeater1->dataBind();
 +		}
 +	}
 +
 +	public function label_changed($sender, $param)
 +	{
 +		$index = $sender->getParent()->ItemIndex + 1;
 +		$this->_status .= " Update textbox {$index}: ".$sender->Text;
 +	}
 +
 +	public function onPreRender($param)
 +	{
 +		parent::onPreRender($param);
 +		if(trim($this->_status))
 +			$this->label1->Text = $this->_status;
 +	}
 +
 +	public function enable_edit($sender, $param)
 +	{
 +		if($this->update_button->Enabled==false)
 +		{
 +			for($i = 0; $i<count($this->repeater1->Items); $i++)
 +			{
 +				$textbox = $this->repeater1->Items[$i]->edit_box;
 +				$textbox->DisplayTextBox = true;
 +			}
 +			$this->update_button->Enabled = true;
 +			$sender->Enabled=false;
 +		}
 +	}
 +
 +	public function disable_edit($sender, $param)
 +	{
 +		if($this->update_button->Enabled==true)
 +		{
 +			for($i = 0; $i<count($this->repeater1->Items); $i++)
 +			{
 +				$textbox = $this->repeater1->Items[$i]->edit_box;
 +				$textbox->DisplayTextBox = false;
 +			}
 +			$this->edit_button->Enabled = true;
 +			$sender->Enabled=false;
 +		}
 +	}
 +}
 +
 +?>
\ No newline at end of file  | 
