Xây dựng website đơn giản, nhanh chóng với JoomCi (CodeIgniter Framework )

Thảo luận trong 'PHP & MYSQL' bắt đầu bởi tuanthuaan, 23/1/15.

  1. tuanthuaan

    tuanthuaan -:- JoomCi -JCi -:-

    Bài viết:
    134
    Likes :
    54
    Sau gần 2 tuần tiến hành thì cuối cùng sản phẩm JoomCi mình phát triển đã hoàn thành. Do khi làm web, khách hàng thường yêu cầu không sử dụng Open Source nên phải tự mình phát triển riêng cho mình một source PHP riêng sẽ hay hơn. Mình thì chuyên về Joomla lại thấy giao diện quản trị Joomla quen thuộc, dễ sử dụng...mình lại có một số kiến thức về CodeIgniter Framework nên thôi thì kết hợp giao diện HTML quản trị của Joomla và code PHP CI Framework và cuối cùng mình đặt tên là JoomCi :13.jpg:
    Demo:
    + Site: http://joomci.zz.vc
    + Admin: http://joomci.zz.vc/admin
    (mình chỉ cấp quyền user là quản trị Tin tức thôi nha), với tài khoản: Tên đăng nhập: user - Mật khẩu: 123456
    Hy vọng được mọi người góp ý và phát triển JoomCi tốt hơn. Cám ơn! :70.jpg:
    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]
     
    Last edited: 10/3/15
    hieuvu899 thích bài này.
  2. chugacon

    chugacon Rất tích cực

    Bài viết:
    75
    Likes :
    2
    xin lổi a trước nha! a có thể chỉ em cho module Tin Đoc Nhiều em chỉnh ở Tempalte chổ js , nó có thể di chuyển lên xuống những nó di chuyển wa menu o dưới luôn. a có thể sửa code dùm em với
    Demo: http://demo22.byethost7.com/index.php/xa-hoi
    Hính 1:
    [​IMG]
    Hình 2:
    [​IMG]
    Mã:
    /**
    *------------------------------------------------------------------------------
    * @package   T3 Framework for Joomla!
    *------------------------------------------------------------------------------
    * @copyright Copyright (C) 2004-2013 JoomlArt.com. All Rights Reserved.
    * @license   GNU General Public License; http://www.gnu.org/licenses/gpl.html
    * @author    JoomlArt, JoomlaBamboo
    *            If you want to be come co-authors of this project, please follow
    *            our guidelines at http://t3-framework.org/contribute
    *------------------------------------------------------------------------------
    */
    
    //jascrollbar
    (function($){
        var javer = 1.0;
        if(window.jasb && window.jasb.version >= javer){
            return false;
        }
      
        var jasb = window.jasb || {};
      
        jasb.instances = jasb.instances || [];
        jasb.options = {
            axis: 'y', //( x || y ).
            wheel: 40,  //wheel amount.
            scroll: true, //enable or disable the mousewheel.
            lockscroll: true, //return scrollwheel to browser if there is no more content.
            size: 'auto', //set the size of the scrollbar to auto or a fixed number.
            sizethumb: 'auto', //set the size of the thumb to auto or a fixed number.  
            minthumb: 10 //the thumb is 10px in minimum.  
        };
      
        $.fn.jascrollbar = function(options) {
            if ( typeof options === 'string' ) {
                var args = Array.prototype.slice.call( arguments, 1 );
    
                this.each(function(){
                    var instance = $.data( this, 'jascrollbar' );
                    if (!instance || !$.isFunction( instance[options] )) {
                        return;
                    }
                  
                    // apply method
                    instance[ options ].apply( instance, args );
                });
              
            } else {
                this.each(function() {
                    var instance = $.data(this, 'jascrollbar');
                    if ( instance ) {
                        instance.update();
                    } else {
                        $.data(this, 'jascrollbar', new jacsb(this, options));
                    }
                });
            }
          
            return this;
        };
      
        function jacsb(root, options){
            this.vars = {
                root: $(root),
                options: $.extend({}, jasb.options, options)
            };
            this.initialize();
            return this;
        }
      
        jacsb.prototype = {
            initialize: function() {
                var vars = this.vars,
                    options = vars.options,
                    root = vars.root;
                  
                vars.viewport = root.find('.viewport');
                vars.content = root.find('.overview');
                vars.scrollbar = root.find('.scrollbar');
                vars.track = vars.scrollbar.find('.track');
                vars.thumb = vars.scrollbar.find('.thumb');
                vars.xaxis = options.axis == 'x';
                  
                vars.dir = vars.xaxis ? 'left' : 'top';
                vars.size = vars.xaxis ? 'Width' : 'Height';
                vars.imove = 0;
                vars.itouch = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
                vars.estart = vars.itouch ? 'touchstart' : 'mousedown';
                vars.emove = vars.itouch ? 'touchmove' : 'mousemove';
                vars.eend = vars.itouch ? 'touchend' : 'mouseup';
                vars.ecancel = vars.itouch ? 'touchcancel' : 'mouseup';
                vars.iscroll = 0;
                vars.ipstart = 0;
                vars.istart = 0;
                vars.inow = 0;
              
                vars.start = $.proxy(this.start, this);
                vars.end = $.proxy(this.end, this);
                vars.drag = $.proxy(this.drag, this);
                vars.wheel = $.proxy(this.wheel, this);
          
                this.update();
                this.addevents();
            },
          
            update: function(pos){
                var vars = this.vars,
                    options = vars.options;
                  
                vars.vpsize = vars.viewport[0]['offset' + vars.size];
                vars.ctsize = vars.content[0]['scroll' + vars.size];
                vars.sbsize = vars.ctsize - vars.vpsize;
                vars.cratio = vars.vpsize / vars.ctsize;
                vars.hasbar = vars.cratio < 1;
              
                if(vars.hasbar){
                    vars.trsize = options.size == 'auto' ? vars.vpsize : options.size;
                    vars.thsize = Math.min(vars.trsize, Math.max(options.minthumb, ( options.sizethumb == 'auto' ? (vars.trsize * vars.cratio) : options.sizethumb )));
                    vars.stsize = vars.trsize - vars.thsize;
                    vars.tratio = vars.sbsize / vars.stsize;
                    vars.iscroll = (pos == 'relative' && vars.hasbar) ? Math.min(vars.sbsize, Math.max(0, vars.iscroll)) : 0;
                    vars.iscroll = (pos == 'bottom' && vars.hasbar) ? vars.sbsize : isNaN(parseInt(pos)) ? vars.iscroll : parseInt(pos);
                    vars.iscroll = Math.min(vars.sbsize, Math.max(0, vars.iscroll));
    
                    vars.thumb.css(vars.dir, vars.iscroll / vars.tratio);
                    vars.content.css('margin-' + vars.dir, -vars.iscroll);
                    vars.istart = vars.thumb.offset()[vars.dir];
                  
                    var prop = vars.size.toLowerCase();
                    vars.scrollbar.css(prop, vars.trsize);
                    vars.track.css(prop, vars.trsize);
                    vars.thumb.css(prop, vars.thsize);
                }
              
                vars.scrollbar.toggleClass('enable', vars.hasbar);
            },
          
            togglesbar: function(tg){
                var vars = this.vars;
                if(!vars.scrollbar.hasClass('enable')){
                    return false;
                };
              
                if(tg){
                    vars.scrollbar.fadeIn();
                } else {
                    vars.scrollbar.fadeOut();
                    vars.thumb.css(vars.dir, 0);
                    vars.content.css('margin-' + vars.dir, 0);
                }
            },
      
            addevents: function(){
                var inst = this,
                    vars = this.vars,
                    options = vars.options;
              
              
                if(vars.itouch){
                    vars.thumb[0].ontouchstart = function(e){
                        e.preventDefault();
                        vars.mode = 0;
                        vars.imove = 0;
                        inst.start(e.touches[0]);
                      
                        return false;
                    };
                  
                    vars.content[0].ontouchstart = function(e){
                        e.preventDefault();
                        vars.mode = 1;
                        vars.imove = 0;
                        inst.start(e.touches[0]);
                      
                        return false;
                    };
                } else {
                    vars.thumb.on('mousedown', vars.start)
                }
              
                if(options.scroll && window.addEventListener){
                    vars.root[0].addEventListener('DOMMouseScroll', vars.wheel, false);
                    vars.root[0].addEventListener('mousewheel', vars.wheel, false);
                }
                else if(options.scroll){
                    vars.root[0].onmousewheel = vars.wheel;
                }
            },
          
            start: function(e){
                var inst = this,
                    vars = this.vars,
                    pos = parseInt(vars.thumb.css(vars.dir));
              
                if(vars.mode == 1){
                    pos = parseInt(vars.content.css('margin-' + vars.dir));
                }
              
                vars.istart = vars.options.xaxis ? e.pageX : e.pageY;
                vars.ipstart = isNaN(pos) ? 0 : pos;
              
                if(vars.itouch){
                    document.ontouchmove = function(me){                  
                        me.preventDefault();
                        inst.drag(me.touches[0]);
                    };
                    vars.thumb[0].ontouchend = document.ontouchend = function(me){
                        inst.end(me);
                    };
                } else {
                    $(document).on('mousemove',  vars.drag).on('mouseup', vars.end);
                    vars.thumb.on('mouseup', vars.end);
                    vars.scrollbar.addClass('dragging');
                }
              
                return false;
            },
          
            wheel: function(e){
                var vars = this.vars;
              
                if(!(vars.cratio >= 1 )){
                    var e = e || window.event,
                        idelta = e.wheelDelta ? e.wheelDelta /120 : -e.detail /3;
                  
                    vars.iscroll -= idelta * vars.options.wheel;
                    vars.iscroll = Math.min(vars.sbsize, Math.max(0, vars.iscroll));
                  
                    vars.thumb.css(vars.dir, vars.iscroll / vars.tratio);
                    vars.content.css('margin-' + vars.dir, -vars.iscroll);
    
                    if( vars.options.lockscroll || ( vars.iscroll !== vars.sbsize && vars.iscroll !== 0 )){
                        e = $.event.fix(e);
                        e.preventDefault();
                    }
                }
            },
          
            end: function(e){
                var vars = this.vars;
              
                if(vars.itouch){
                    document.ontouchmove = document.ontouchend = vars.thumb[0].ontouchend = null;
                }else{
                    $(document).off('mousemove', vars.drag).off('mouseup', vars.end);
                    vars.thumb.off('mouseup', vars.end);
                    vars.scrollbar.removeClass('dragging');
                }
              
                if(vars.itouch && !vars.imove){
                    var ce = e.changedTouches[0],
                        target = ce.target;
                  
                    while (target.nodeType != 1){
                        target = target.parentNode;
                    }
    
                    if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {
                        var ev = document.createEvent('MouseEvents');
                        ev.initMouseEvent('click', true, true, e.view, 1,
                            ce.screenX, ce.screenY, ce.clientX, ce.clientY,
                            e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
                            0, null);
                        ev._fake = true;
                        target.dispatchEvent(ev);
                    }
                }
              
                return false;
            },
          
            drag: function(e){
                var vars = this.vars;
                vars.imove = 1;
                if(!(vars.cratio >= 1)){
                    if(vars.mode == 1){
                        vars.iscroll = -Math.min(0, Math.max(-vars.sbsize, (vars.ipstart + ((vars.xaxis ? e.pageX : e.pageY) - vars.istart))));
                        vars.inow = vars.iscroll / vars.tratio;
                    }else {
                        vars.inow = Math.min(vars.stsize, Math.max(0, (vars.ipstart + ((vars.xaxis ? e.pageX : e.pageY) - vars.istart))));
                        vars.iscroll = vars.inow * vars.tratio;
                    }
                  
                    vars.content.css('margin-' + vars.dir, -vars.iscroll);
                    vars.thumb.css(vars.dir, vars.inow);
                }
              
                return false;
            },
          
            options: function(opts){
                $.extend(this.vars.options, opts);
            }
        };
    })(jQuery);
    
    //
    (function($){
        $(document).ready(function(){
    
            //initilized affix
            (function(){
                var wnd = $(window),
                    mainnav = $('#t3-mainnav'),
                    sidebar = $('.sidebar-affix'),
                    inset = $('.t3-inset');
    
                if((('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) && (inset.length && inset.offset().top > $(window).height() / 2)) {
                    return false;
                }
      
                sidebar.css('position', 'static');
                inset.css('position', 'static');
                $(document.body).css('min-height', Math.max($(window).height(),
                    inset.length ? inset.offset().top + 80 + Math.min($(window).height(), inset.height()) : 0,
                    sidebar.length ? sidebar.offset().top + 80 + sidebar.height() : 0));
                sidebar.css('position', '');
                inset.css('position', '');  
    
                if(sidebar.length){
                    var sidebarprev = sidebar.prev();
                    if(!sidebarprev.length){
                        sidebarprev = sidebar.parent();
                    }
    
                    sidebar.affix({
                        offset: {
                            top: function () {
                                return sidebarprev.offset().top + sidebarprev.outerHeight(true) - 80
                            }
                        }
                    });
                }
    
                if(inset.length){
              
                    var insetprev = inset.prev();
    
                    if(!insetprev.length){
                        insetprev = inset.parent();
                    }
    
                    inset.affix({
                        offset: {
                            top: function () {
                                return insetprev.offset().top - 80
                            }
                        }
                    });
                }
    
                if(sidebar.length || inset.length){
                    var rzid = null,
                    resize = function(){
                        sidebar.width(sidebarprev && sidebarprev.width() ? sidebarprev.width() : sidebar.parent().width());
                        inset.width(insetprev && insetprev.width() ? insetprev.width() : inset.parent().width());
    
                        $(window).trigger('scroll.affix.data-api');
                    };
    
                    wnd.on('resize orientationchange', function(){
                        clearTimeout(rzid);
                        $(window).trigger('scroll.affix.data-api');
                        rzid = setTimeout(resize, 200);
                    });
    
                    resize();
                }
            })();
          
            //initilized infinitescroll
            (function(){
                var itemSelector = '.items-row',
                    contentSelector = '.infinitescroll',
                    infinitescroll = $('.infinitescroll');
              
                if(!infinitescroll.length){
                    itemSelector = '.itemContainer';
                    contentSelector = '#k2Container .itemList';
                    infinitescroll = $(contentSelector).length ? $('#k2Container') : {};
                }
    
                if(!infinitescroll.length){
                    itemSelector = '.userItemView';
                    contentSelector = '#k2Container .userItemList';
                    infinitescroll = $(contentSelector).length ? $('#k2Container') : {};
                }
              
                if(!infinitescroll.length){
                    itemSelector = '.tagItemView';
                    contentSelector = '#k2Container .tagItemList';
                    infinitescroll = $(contentSelector).length ? $('#k2Container') : {};
                }
    
                if(!infinitescroll.length){
                    return false;
                }
    
                var pathObject = {
                    init: function(){
                        this.path = ($('#page-next-link').attr('href') || '');
                        var match = this.path.match(/((page|limitstart|start)[=-])(\d*)(&*)/i);
                        if(match){
                            this.type = match[2].toLowerCase();
                            this.number = match[3];
                            this.limit = this.type == 'page' ? 1 : this.number;
                            this.number = this.type == 'page' ? this.number : 1;
                        } else {
                            this.type = 'unk';
                            this.number = 2;
                            this.path = this.path + (this.path.indexOf('?') == -1 ? '?' : '') + 'start=';
                        }
    
                        var urlparts = this.path.split('#');
                        if(urlparts[0].indexOf('?') == -1){
                            urlparts[0] += '?tmpl=component';
                        } else {
                            urlparts[0] += '&tmpl=component';
                        }
    
                        this.path = urlparts.join('#');
                    },
                  
                    join: function(){
                        if(pathObject.type == 'unk'){
                            return pathObject.path + pathObject.number++;
                        } else{
                            return pathObject.path.replace(/((page|limitstart|start)[=-])(\d*)(&*)/i, '$1' + (pathObject.limit * pathObject.number++) + '$4');
                        }
                    }
                };
                pathObject.init();
    
    
                infinitescroll.infinitescroll({
                    loading: {
                        finished: undefined,
                        finishedMsg: T3JSVars.finishedMsg,
                        img: T3JSVars.tplUrl + '/images/ajax-load.gif',
                        msg: null,
                        msgText: T3JSVars.msgText,
                        selector: null,
                        speed: 'fast',
                        start: undefined
                    },
                    state: {
                        isDuringAjax: false,
                        isInvalidPage: false,
                        isDestroyed: false,
                        isDone: false, // For when it goes all the way through the archive.
                        isPaused: false,
                        currPage: 0
                    },
                    debug: false,
                    behavior: undefined,
                    binder: $(window), // used to cache the selector for the element that will be scrolling
                    nextSelector: '#page-next-link',
                    navSelector: '#page-nav',
                    contentSelector: contentSelector, // rename to pageFragment
                    extraScrollPx: 150,
                    itemSelector: itemSelector,
                    animate: false,
                    pathParse: pathObject.join,
                    dataType: 'html',
                    appendCallback: true,
                    bufferPx: 350,
                    errorCallback: function () { },
                    infid: 0, //Instance ID
                    pixelsFromNavToBottom: undefined,
                    path: pathObject.join, // Can either be an array of URL parts (e.g. ["/page/", "/"]) or a function that accepts the page number and returns a URL
                    prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted
                    maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work)
                }, function(){
                    if(typeof DISQUSWIDGETS != 'undefined'){
                        DISQUSWIDGETS.getCount();
                    } else if(typeof disqus_shortname != 'undefined') {
                        $.getScript('http://'+disqus_shortname+'.disqus.com/count.js');
                    }
                });
    
            })();
    
    
            //initlized mega-dim
            (function(){
    
                var dim = $('<div class="mega-dim"></div>').appendTo(document.body),
                    btnnav = $('.btn-navbar:first'),
                    retain = [];
    
                $('#t3-mainnav .nav > li').hover(function(event) {
                    if(btnnav.css('display') == 'none' || $(this).closest('.nav').parent().hasClass('head-social')){      
                        if($.inArray(this, retain) == -1){
                            retain.push(this);
                        }
                        clearTimeout ($(this).data('dimTimeout'));
                        dim.addClass('active');                  
                    }
                },
                function(event) {
                    if(dim.hasClass('active')){
                        var that = this;
                        $(this).data('dimTimeout',
                            setTimeout(function(){
                                retain = $.grep(retain, function(item){
                                    return item != that;
                                });
    
                                if(retain.length <= 0){
                                    dim.removeClass('active');
                                }
    
                            }, 100));
                    }
                });
    
                dim.on('click', function(){
                    $(document).trigger('hidesub');
                    retain.length = 0;
                    dim.removeClass('active');
                });
          
            })();
    
            //initilized scrollbar
            (function(){
    
                var sid = null,
                    scrollbar = $('.t3-inset.scrollcontainer'),
                    overview = scrollbar.find('.overview:first'),
                    viewport = scrollbar.find('.viewport:first'),
    
                    resize = function(){
                        var    wheight =  Math.min(overview.height(), Math.max($(window).height() - 80));
      
                        viewport.css('height', wheight);
                      
                        scrollbar.jascrollbar('options', {
                            size: wheight
                        }).jascrollbar('update', 'relative');
                    };
    
                viewport.after('<div class="scrollbar"><div class="track"><div class="thumb"><div class="end"></div></div></div></div>');
                viewport.css('height', Math.min(overview.height(), $(window).height() - 80));
                scrollbar.find('.scrollbar').css('top', viewport.prev().outerHeight(true));
                scrollbar.addClass('scrollcontainer').jascrollbar();
    
                $(window).on('resize.sbar', function(){
                    clearTimeout(sid);
                    sid = setTimeout(resize, 500);
                }).trigger('resize.sbar');
    
                $(window).load(function(){
                    var active = overview.find('li.active .mod-articles-category-title, .mod-articles-category-title.active');
                    if(!active.length){
                        active = overview.find('li.active .moduleItemTitle, .moduleItemTitle.active');
                    }
    
                    scrollbar.jascrollbar('update', active.length ? (active.offset().top - overview.offset().top) : 'relative');
                });
    
            })();
        });
    
    })(jQuery);
    
    
     
  3. hieuvu899

    hieuvu899 Mới tham gia

    Bài viết:
    20
    Likes :
    1
    JoomCi của bác rất hay. Em biết joomla cũng được 1 năm rồi. giờ muốn phát triển joomla theo ý mình như bác nhưng khó quá. bác có thể chia sẻ chút kinh nghiệm giúp em được không ạ. Như JoomCi của bác thì em cần biết những ngôn ngữ gì ạ.
     
  4. tuanthuaan

    tuanthuaan -:- JoomCi -JCi -:-

    Bài viết:
    134
    Likes :
    54
    Cám ơn bạn đã quan tâm. Mình cũng chia sẻ thế này nha:
    + Bạn nói là bạn biết Joomla cũng hơn 1 năm: bạn hãy ngẫm nghĩ lại là bạn biết được gì rồi? Bạn biết sử dụng hay là bạn biết phát triển các extensions ? Bạn đã tự code được 1 component, 1 module, 1 plugin, 1 template riêng cho mình được không? Nếu bạn chưa làm được có nghĩa là bạn đang ở mức người sử dụng được joomla. Còn được thì bạn ở mức người phát triển được joomla và bạn có thể phát triển Joomla theo ý bạn nói.
    + Còn về JoomCi của mình phát triển thì không liên quan gì đến Joomla chỉ trừ giao diện HTML quản trị thì mình sử dụng giao diện HTML Administrator của Joomla 2.5 (vì nó đơn giản, và quen thuộc rồi ^^)
    + Nếu bạn muốn phát triển giống JoomCi chẳng hạn thì bạn cần một số kiến thức căn bản sau:
    + PHP (1)
    + MySQL
    + HTML + CSS + JAVACRIPT
    + 1 FRAMEWORK mà bạn thấy hay và dễ học (vd: Codeigniter Framework, Zend Framework...) (2)
    => (2) sẽ cấu trúc theo mô hình MVC cho dễ sử dụng và có thư viện các hàm có sẵn chỉ gọi và sử dụng thay vì phải viết cho (1) :D, kệ đi nôm na hiểu vậy đi...
    Đó chỉ vậy thôi, nếu bạn là sinh viên Công nghệ thông tin thì bạn được trang bị hết, nhưng cái Framework thì chỉ được giới thiệu và tự tìm hiểu...ai thích cái nào thì tự học cái đó rồi năm cuối làm đồ án ;););)
    Chúc bạn thành công!
     
    hieuvu899 thích bài này.
  5. moitruongdgp

    moitruongdgp Mới tham gia

    Bài viết:
    10
    Likes :
    0
    Phải công nhận sau khi làm bên wordpress xong qua joomla nhìn cái choáng luôn
     
  6. hieuvu899

    hieuvu899 Mới tham gia

    Bài viết:
    20
    Likes :
    1
    cám ơn bác nhé. em có phát triển được template rồi, giờ tìm hiểu mấy cái Framework chắc là ok. em làm nhiều bằng wordpress nên qua joomla thấy hơi khó
     
  7. tuanthuaan

    tuanthuaan -:- JoomCi -JCi -:-

    Bài viết:
    134
    Likes :
    54
    :) một source code mới của joomci vừa xong "HỆ THỐNG THI TRẮC NGHIỆM TRỰC TUYẾN". Demo: Site: http://demochat.byethost18.com/tracnghiem . (Mã đề thi xem trong phần quản trị đề thi) Admin: http://demochat.byethost18.com/tracnghiem/login (User: admin, Pass: 123456) - Mã đề: 2669776 chỉ được phép thì trong ngày 16/11/2015 (do đề thi thiết lập thi trong ngày này)
    AI CẦN LIÊN HỆ NHA - GIÁ CẢ HỢP LÝ ^^
    + Hệ thống phân quyền 2 cấp: quản trị hệ thống và quản trị đề thi. Quản trị hệ thống sử dụng toàn bộ chức năng cũng như câu hỏi, đề thi. Quản trị đề thi chỉ sử dụng câu hỏi, đề thi của mình.
    + Câu hỏi có 2 loại: câu hỏi 1 đáp an và câu hỏi nhiều đáp án với 3 mức độ dễ, tb, khó. Tùy theo đề thi mà câu hỏi dễ, tb, khó tương ứng. Câu hỏi cũng có thể được import từ file excel được nhập theo mẫu
    + Đề thì sẽ ngẫu nhiên chọn trong ngân hàng đề thì của môn tương ứng và phần trả lời cũng ngẫu nhiên được trộn. Do đó, cùng 1 đề thi nhưng câu hỏi không giống nhau và phần trả lời cũng vậy (đã được trộn) (^^ sẽ tránh thí sinh hỏi nhau nếu thi trong phòng thi)
    + Thời gian làm bài thi sẽ tự động đếm ngược, khi refesh trang (F5) thì đề thi không thay đổi, câu trả lời được chọn cũng giữ nguyên, thời gian đếm ngược vẫn tiếp tục. Khi hết giờ làm bài thì hệ thống sẽ tự nộp bài. Nếu gặp sự cố không tự động nộp bài (do lỗi trình duyệt hay người thi cố tình can thiệp) thì trong vòng 15 giây không nộp bài, bài thi sẽ không được lưu.
    + Quản trị đề thi có thể xem kết quả thi, kết quả trả lời từng câu của thí sinh, thí sinh dự thi (đã nộp bài hay không)....Ngoài ra có thể xuất file Excel kết quả điểm số của thí sinh dự thi...
    .... vài chức năng cơ bản nhưng đủ đề sử dụng trong hệ thống thi trắc nghiệm tại trường học...
    Cám ơn các bạn đã theo dõi. Bạn nào cần thì liên hệ mình với giá phải chăng. Bạn nào không cần thì có thể tham khảo và góp ý nha. Trân trọng!
    Email: [email protected]
     
  8. nhahome93

    nhahome93 Mới tham gia

    Bài viết:
    4
    Likes :
    0
    Nhìn giống joomla như đúc ấy bác nhỉ.
     
comments powered by Disqus

Chia sẻ trang này