Click here to Skip to main content
Licence CPOL
First Posted 8 Feb 2008
Views 11,549
Downloads 49
Bookmarked 18 times

Mark Notation System

By | 21 Feb 2008 | Article
A webcontrol for the notation

Introduction

Sample Image

Today, many comparator sites give the possibility to assign a mark to a product or a service. Several controls can be used to do this. Today I submit mine: the webstarcontrol.

The big advantage to my program is that you can put several controls on the same page and you manage them as you want. The webstarctrl has 2 modes:

  • Edit mode: The website visitor who assigns the mark can select his/her own mark.
  • Read mode: The website visitor watches the average mark (represented by stars). He is just an observer of the mark.
    This code allows you to easily integrate a very simple mark system on your website. It's useful because it is very simple to parametrize.

Background

To use this control, you need to provide parameters:

  • InternalId is required and each control must have a unique ID (like ID property)
  • ImgScrOk is the path of the picture when selected. It's a required property
  • ImgScrKo is the path of the picture when not selected. It's a required property
  • NbrStar is the maximal mark you can give. It's a required property
  • IsReadOnly displays the control in consultation (without handling an event click) when it takes the true value. It's an optional property.
  • InitialValue select a number at the initialisation of the control.

Using the Code

To use this control, you must add three things on your project:

  • the CtrlStar webcontrol class (CtrlStar.cs).
  • the JavaScript file starhelper.js. (the path of this file is parametrized on the OnInit method of the CtrlStar.cs file.
  • the pictures you want to display parametrized on ImgScrOk and ImgScrKo properties.

The main difficulty I encountered in developing this control was to be able to separate all the instances of the controls in one page. The JavaScript file allows us to dynamically generate HTML, and it builds its different HTML Objects with concatenation of the internalId to separate each control. IE and its other brothers don't have the same JavaScript implementation, and you must write different code for each brother.

function BuildStars(pStarNumber , pIdDivContainer , pImgScrOk , pImgScrKo, pReadOnly ,
    pInitValue)
    {
       
       if(pImgScrKo == '')
        {
            alert('You must specify the image path KO');
            return ;
        }
       if(pImgScrOk == '')
        {
            alert('You must specify the image path OK');
            return ;
        }
        if(pStarNumber == '')
        {
            alert('You must specify stars number');
            return ;
        }
        if(pIdDivContainer =='')
        {
            alert('You must specify the div Id Container');
            return ;
        }
        
        if(! document.getElementById(pIdDivContainer))
        {
            alert('Not found div Id in document');
            return;
        }
        var i;
        var idContainer = document.getElementById(pIdDivContainer);
        
        
        var table = document.createElement('table');
        table.setAttribute('id', 'table'+pIdDivContainer);
        table.setAttribute('border','0');
        idContainer.appendChild(table);
        
        // tbody is required for IE and understood by Mozilla
        var tbody = document.createElement('TBODY');
        table.appendChild(tbody);
        var tr = document.createElement('tr');
        tr.setAttribute('id',"tr"+pIdDivContainer);
        tbody.appendChild(tr);
        
     
        for( i = 0 ; i < pStarNumber ; i++)
        {
        
            var td = document.createElement('td');
            td.setAttribute('id', 'td'+pIdDivContainer+i);
            
            var hlink = document.createElement('a');
            hlink.setAttribute('id', 'a'+pIdDivContainer+i);
            var nb = i+1;
            
            //case IE
            if( IsIE()  )
            {
        
                  hlink.attachEvent("onclick", function(e){
                  
                        
                        //step 1 : find link click event source
                        var varIdValue;
                        var Obj;
                        
                        if( !e) e = event;
                        
                        if( e.target)
                        {
                            Obj= e.target;
                        }
                        else
                        {
                          Obj = e.srcElement;
                          while(Obj.parentNode)
                          {
                            Obj= Obj.parentNode;
                            //-- Si c'est un lien
                            if( Obj.tagName == "A") 
                            {   
                               varIdValue = Obj.id;
                            }
                          }
                        }
                        
                        //a + length of pIdDivContainer
                        var nbr = 1 + pIdDivContainer.length;
                        var idValue = varIdValue.substr(nbr , varIdValue.length - nbr);
                        idValue ++;
                               
                        //step 2 : find link click event source     
                        setStar(idValue , pStarNumber , pIdDivContainer,pImgScrOk,
                            pImgScrKo);
                        

                    }
                  )

            } 
            else //FireFox , safari ,netscape
            {
                hlink.setAttribute("onclick","setStar("+nb+","+pStarNumber+",
                    '"+pIdDivContainer+"','"+pImgScrOk+"','"+pImgScrKo+"')");
            }
            
            
            var imgo = new Image();
            imgo.id='img'+pIdDivContainer+i;
            // Set init Value
            if(pInitValue > 0)
            {
                if(nb <= pInitValue)
                    {imgo.src=pImgScrOk;}
                else
                    {imgo.src=pImgScrKo;}
            }
            else
                {imgo.src=pImgScrKo;}
            
            imgo.border='0';
             
            
            tr.appendChild(td);
            
             //Normal Mode
             if(pReadOnly == '0')
             {
                td.appendChild(hlink);
                hlink.appendChild(imgo);
             }
             //ReadOnlyMode Mode
             else
             {
                td.appendChild(imgo);
             }
            
        }
        
        var currentSelected = document.createElement('input');
        currentSelected.id='hiddenVal'+pIdDivContainer;
        currentSelected.setAttribute('type','hidden');
        
        if(pInitValue > 0)
        {
            currentSelected.setAttribute('value',pInitValue);
        }
        else
            {currentSelected.setAttribute('value','0');}
        
        idContainer.appendChild(currentSelected);
        
    }

The star click event is handling on the JavaScript function setStar and this function call the method client setCurrentNumber whose trigger is a Server side AJAX CallBack.

   // ##### star click eventhandler############
    function setStar(pNumber,totalStar,IdDivContainer,pImgScrOk,pImgScrKo)
    {
        var i;
        
        for(i=0 ;  i < pNumber ; i++)
        {
        
            if(document.getElementById('img'+IdDivContainer+i))
            {
                var curImg = document.getElementById('img'+IdDivContainer+i);
                curImg.src = pImgScrOk;
            }
        }
        for(i=pNumber ;  i <= totalStar ; i++)
        {
            if(document.getElementById('img'+IdDivContainer+i))
            {
                var curImg = document.getElementById('img'+IdDivContainer+i);
                curImg.src = pImgScrKo;
            }
        }
        
        divContainer = document.getElementById(IdDivContainer);
        oldNode = document.getElementById('hiddenVal'+IdDivContainer);
        
        var currentSelected = document.createElement('input');
        currentSelected.id='hiddenVal'+IdDivContainer;
        currentSelected.setAttribute('type','hidden');
        currentSelected.setAttribute('value',pNumber);    
        
        divContainer.replaceChild(currentSelected,oldNode);
        
        setCurrentNumber(pNumber,IdDivContainer);
        
    
    }

To use AJAX Functionality, Pages and/or Controls, you must implement the ICallBackEventHandler interface defining methods GetCallbackResult() and RaiseCallbackEvent() Server side. You need to "connect" the Client side call to the server side on the OnInit Control method.

 public class CtrlStar : WebControl, ICallbackEventHandler
    {
    ...
    
       /// <summary />
        /// Init Event
        /// </summary />
        /// <param name=""e"" /></param />
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            StreamReader fp = File.OpenText(Page.Server.MapPath("~/") + "\\js\\" +
                "starhelper.js");
            string js = fp.ReadToEnd();
            fp.Close();


            
            Page.ClientScript.RegisterClientScriptBlock(
               this.GetType(),
               "scrManager",
               js.ToString(),
               true);


           
            string ReferenceVersFonctionClienteInitiatriceDuCallBack = 

            Page.ClientScript.GetCallbackEventReference(
            
this, 
            
"arg", 
            
"FunctionCallBack", 
            
"context", 
            
"FunctionCallBackError", 
            
false);
            string ScriptFonctionCliente = 

            "function ExecuteCallBack(arg,context){" +
                ReferenceVersFonctionClienteInitiatriceDuCallBack + ";}";
            Page.ClientScript.RegisterClientScriptBlock(
                this.GetType(),
                "callback",
                ScriptFonctionCliente,
                true);


            HtmlGenericControl h = new HtmlGenericControl();
            h.TagName = "div";
            h.ID = InternalId;
            this.Controls.Add(h);


        }
    
        public string GetCallbackResult()
        {

            return "";

        }
  
        public void RaiseCallbackEvent(string eventArgument)
        {
            string[] tks = eventArgument.Split(';');
            setNbrClickedStar(tks[0], tks[1]);

        }
    
    }

For the client side on the JavaScript starhelper.js file, you must provide these reference methods:

    function FunctionCallBack(result, context)
    {} 
              
    function FunctionCallBackError(result, context)
    {}
              
    function setCurrentNumber(pCurrentNumber , pIdDivContainer)
    {
        var str = pIdDivContainer+";"+pCurrentNumber;
        ExecuteCallBack(str,'context');
    }

Points of Interest

I have learned how to create an ASP.NET Web control with a complete JavaScript treatment. I discovered the fundamental differences between IE and others browsers.

Thanks

Thanks to Phillipe Pele for his JavaScript compatibility help (IE / FireFox etc...)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

David Zenou

Software Developer
Several
France France

Member

I am a Fan of dotnet technologies. I began to work with Java j2ee technologies and today i made my choice : .Net Framework is very pleasant , has excellents article codes and documentation.
I found very useful articles in codeproject , and today i want to give my contribution , and i hope that my articles will be useful.
 
Go to see my blog : http://davidzenou.blogspot.com/2009/01/david.html

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generalwhat's going on Pinmembertrobertz17:50 8 Feb '08  
GeneralRe: what's going on Pinmemberdreamer9222:22 8 Feb '08  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120528.1 | Last Updated 21 Feb 2008
Article Copyright 2008 by David Zenou
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid