2014-11-11 7 views
0

У меня есть выпадающее меню, которое каждый день используется множеством разных людей.Как выбрать сортировку по популярности?

Наша идея состояла в том, чтобы персонализировать этот выбор для пользователей.

Так, например, пользователь делает следующий выбор:

- Option a: 5 times 
- Option c: 3 times 
- Option f: 1 time 

Тогда мы хотели бы, чтобы выбрать заказываются A, C, F, B, D, E. Короче говоря, мы хотим, чтобы самые популярные предметы для этого пользователя показывались сверху.

Теперь, конечно, я знаю, что я мог бы сделать такое, используя jquery и cookie, но мне было интересно, есть ли решение вокруг этого.

Редактировать: Я уже искал это, но не нашел ничего похожего на то, что искал.

+0

Таким образом, вы хотели бы сохранить, сколько раз человек выбран определенный вариант? Как вы загружаете эти параметры в настоящее время? – carlosherrera

+0

Параметры взяты из моей базы данных mysql. Однако строка позиции не является опцией, так как это не решение для каждого пользователя – Peter

+0

, откуда берутся данные для вашего выбора? – baao

ответ

1

Для персонализации select так, что он показывает список option с отсортированных в порядке «Наиболее часто используемых» из них, мы можем иметь лучшее из обоих мира в свой список желаний. Давайте создадим его с помощью jQuery и файлов cookie. А также сделайте повторно используемое решение, готовое к использованию. С дополнительным преимуществом вы можете изменить его по своему вкусу.

Прежде чем мы это сделаем, просто обратите внимание на осторожность. Если вы хотите персонализировать много вещей, тогда лучше сделать это на стороне сервера и создать подсистему персонализации в своем приложении. Опираясь на куки-файлы на стороне клиента, не рекомендуется для таких сценариев.Однако, если ваш прецедент - это всего лишь одноразовый сценарий, такой как этот, где вы просто хотите улучшить пользовательский интерфейс, предоставляя дополнительное усовершенствование помимо рабочего набора функций без внесения изменений в код на стороне сервера, тогда имеет смысл реализовать такую ​​функциональность на стороне клиента. Именно поэтому файлы cookie и localstorage существуют. Подобно тому, как рекламодатели используют файлы отслеживания, это также похоже на файл cookie отслеживания, который отслеживает, что ваши пользователи используют чаще. Не так ли?

Сказанное, давайте создадим плагин jQuery, который вы можете использовать как есть. Он также позволит вам применить его к нескольким select. Назовем это .mfu().

Примечание: Код здесь - просто грубая демонстрация для вас. Он не оптимизирован и, возможно, нуждается в повторном факторинге. В настоящее время этот плагин не сработает, если вы не дадите уникальный id всем вашим select s, так как он зависит от id, чтобы прикрепить и восстановить частоту.

Вы можете просмотреть полную демонстрацию здесь: http://jsfiddle.net/abhitalks/u5z868d0/

Выберите опцию из обоих select с и держать кнопку «запустить» в скрипку. Вы увидите, что наиболее часто используемые параметры продолжают расти.


Начнет с пустым шаблоном плагина, который выглядит следующим образом:

(function ($) { 
    $.fn.extend({ 
     mfu: function() { 
      .... 
      return this.each(function() { 
       ... 
      }); 
     } 
    }); 
})(jQuery); 

Мы проходим каждый из select с, на которой плагин был призван и вернуть их все обратно для построения цепочки ,

Вы можете назвать этот плагин на все ваши выбирает, как это:

$(select).mfu(); 

Мы будем хранить наши option детали вместе с частотами в массиве объектов для всех select с указанным в селекторе, на котором вызывается плагин. Массив объекта выглядит так:

[ 
    { 
     'id': 'drop1', 
     'mfu': 
      [ 
       { 'value': 'a', 'caption': 'Red', 'frequency': 0 }, 
       { 'value': 'b', 'caption': 'Green', 'frequency': 0 }, 
       ... 
      ] 
    }, 
    { 
     'id': 'drop2', 
     'mfu': 
      [ 
       { 'value': '1', 'caption': 'One', 'frequency': 0 }, 
       { 'value': '2', 'caption': 'Two', 'frequency': 0 }, 
       ... 
      ] 
    } 
]; 

Теперь давайте начнем кодирование плагина. Первое, что нужно сделать, это немного инициализировать материал. Мы будем хранить «частоту» каждого option в каждом select для наших «наиболее часто используемых» элементов в файле cookie. Таким образом, наш код инициализации будет включать код для чтения cookie при инициализации и загрузки элементов «наиболее часто используемых» в массив объектов. Нам также нужно будет написать файл cookie, поэтому давайте создадим функцию, чтобы сделать это здесь. Потому что мы будем работать с массивом объектов, мы будем использовать JSON для stringify(), чтобы он записывался в файл cookie, и parse() на чтение.

Итак, наш плагин теперь начинает выглядеть так:

(function ($) { 
    $.fn.extend({ 
     mfu: function() { 
      var self = this, cookieName = 'mfu', 
       defaultExpiry = new Date(2050, 1, 1), 
       getCookie = function(name) { 
        var results = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); 
        return results ? unescape(results[2]) : null; 
       }, 
       setCookie = function(name, value) { 
        var cookieString = name + "=" + escape(JSON.stringify(value)); 
        cookieString += "; expires=" + defaultExpiry.toGMTString(); 
        document.cookie = cookieString; 
       }, 
       mfuStored = getCookie(cookieName), 
       mfuList = JSON.parse(mfuStored) 
      ; 

      return self.each(function() { 
       ... 
      }); 
     } 
    }); 
})(jQuery); 

Мы жестко закодировано название печенья, как «MFU». Мы также установили дату истечения срока действия cookie. В реальном коде вы должны изучить динамически эту настройку.Тогда есть обычные функции чтения/записи для файлов cookie. Мы читаем файл cookie и загружаем список MFU в переменную mfuList, которая является массивом объектов.

Далее мы просматриваем каждый из select s, на который был вызван плагин, а затем выполните поиск в нашем массиве объектов для id каждого select. Если он не найден, значит, он был запущен в первый раз (и/или cookie недоступен), в этом случае мы создаем новый объект для хранения частот. Если найдено, мы найдем option s в том, что select и проверьте, доступны ли частоты при загрузке файлов cookie. Если не найдено, мы создаем новые объекты для хранения данных option.

После этого мы отсортируем наш массив объектов для текущего select, а затем заменим selectoption s в отсортированном виде. Мы также можем показывать частоты пользователю, если это необходимо.

Теперь, все, что остается, чтобы связать change событие на каждом select обновить частоту в массиве объектов выбранного option и сохранить, что обратно в печенье. В этой демонстрации мы сохраняем ее на событии change. В реальной жизни вы можете сохранить файл cookie при разгрузке страницы.

Итак, теперь наш полный плагин выглядит следующим образом:

(function ($) { 
    $.fn.extend({ 
     mfu: function() { 
      var self = this, cookieName = 'mfu', 
       defaultExpiry = new Date(2050, 1, 1), // far ahead expiry of cookie 
       getCookie = function(name) {   // routine to read cookie 
        var results = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); 
        return results ? unescape(results[2]) : null; 
       }, 
       setCookie = function(name, value) { // routine to write cookie 
        var cookieString = name + "=" + escape(JSON.stringify(value)); 
        cookieString += "; expires=" + defaultExpiry.toGMTString(); 
        document.cookie = cookieString; 
       }, 
       mfuStored = getCookie(cookieName), // read the cookie 
       mfuList = JSON.parse(mfuStored)  // parse object array from the string 
      ; 

      return self.each(function() { 
       var select = this, mfu; 
       if (! mfuList) {   // for the first time, create object 
        mfuList = []; mfuList.push({ 'id': select.id, 'mfu': [] }); 
       } 

       // search for the current select 
       mfu = mfuList.filter(function(o) { 
        return o.id === select.id; 
       })[0]; 

       if (!mfu) { // if not found, create object and add to array 
        mfuList.push({ 'id': select.id, 'mfu': [] }); 
        mfu = mfuList[mfuList.length - 1].mfu; 
       } else { 
        mfu = mfu.mfu; // if found, use the mfu property 
       } 

       // for each option search the object arrat 
       [].map.call(select.options, function(option) { 
        var opt = mfu.filter(function(o) { 
         return o.value === option.value; 
        })[0]; 
        if (! opt) { // if not found, create object and add to array 
         opt = {} ; 
         opt.value = option.value; 
         opt.caption = option.innerText; 
         opt.frequency = 0; 
         mfu.push(opt); 
        } 
       }); 

       // sort the array on frequency 
       mfu.sort(function(a, b) { return a.frequency < b.frequency }); 

       // empty the select 
       $(select).empty(); 

       // loop thru our object array and to select in sorted order 
       mfu.forEach(function(item) { 
        var $opt = $("<option>"); 
        $opt.val(item.value); 
        $opt.text(item.caption + ': (' + item.frequency + ')'); 
        $(select).append($opt); 
       }); 

       // add event listener for change 
       $(select).on("change", function() { 
        var value = this.value; 
        // search our object array 
        var opt = mfu.filter(function(o) { 
         return o.value === value; 
        })[0]; 
        opt.frequency++; // increment the frquency 
        setCookie(cookieName, mfuList); // write back the cookie 
       }); 
      }); 
     } 
    }); 
})(jQuery); 

// call the plugin on all selects 
$("select").mfu(); 

Это все есть на него. Теперь вы можете импровизировать и улучшить этот код, если это необходимо, в противном случае он будет готов к использованию как есть.

.

2

Если вы хотите персонализировать свой сайт пользователям, я бы рекомендовал избегать решений на стороне клиента и полагаться только на сервер. Вы никогда не знаете, когда, например, будет удален ваш пользователь localStorage. Также вы можете персонализировать дополнительные данные в будущем, и это может стать не очень масштабируемым.

Мое решение состояло в том, чтобы сохранить дополнительную таблицу в базе данных с внешним ключом для вашего идентификатора пользователя (предположим, вы храните их в списке), что сохраняет его предпочтения. Вы должны обновить эту таблицу после каждого выбора, который делает пользователь (например, размещение формы на вашем сайте -> обновление этой таблицы).

Теперь, когда вы загружаете эту страницу, которую хотите персонализировать, загрузите клиенту ваши варианты выбора, упорядоченные в соответствии с предпочтениями пользователя, то есть в соответствии с новой таблицей в базе данных.

+1

Согласовано. Это обеспечивает решение в правильном направлении, а не просто «ответ». – Leo

0

я сделал некоторые небольшие ДОУ на это, есть у вас есть данные, как может раз пользователь нажал на вариант, этот РОС может использовать полный для вас

HTML код:

<select id="selectbox"> 
    <option data-sort="9">option 1</option> 
    <option data-sort="8">option 2</option> 
    <option data-sort="1">option 3</option> 
    <option data-sort="3">option 4</option> 
    <option data-sort="4">option 5</option> 
    <option data-sort="5">option 6</option> 
    <option data-sort="6">option 7</option> 
    <option data-sort="1">option 8</option> 
    <option data-sort="1">option 9</option> 
    <option data-sort="3">option 10</option> 
    <option data-sort="4">option 11</option> 
    <option data-sort="7">option 12</option> 
    <option data-sort="8">option 13</option> 
    <option data-sort="2">option 14</option> 
    <option data-sort="1">option 15</option> 
    <option data-sort="4">option 16</option> 
</select> 

JQuery код:

function srt(on,descending) { 
     on = on && on.constructor === Object ? on : {}; 
     return function(a,b){ 
      if (on.string || on.key) { 
      a = on.key ? a[on.key] : a; 
      a = on.string ? String(a).toLowerCase() : a; 
      b = on.key ? b[on.key] : b; 
      b = on.string ? String(b).toLowerCase() : b; 
      // if key is not present, move to the end 
      if (on.key && (!b || !a)) { 
       return !a && !b ? 1 : !a ? 1 : -1; 
      } 
      } 
      return descending ? ~~(on.string ? b.localeCompare(a) : a < b) 
          : ~~(on.string ? a.localeCompare(b) : a > b); 
      }; 
     } 
     var boxarray=[]; 
     $("#selectbox").click(function(){ 
      boxarray=[]; 
      $("#selectbox option").each(function(){ 
       var cValue = $(this).val(); 
       var Cattr = $(this).attr("data-sort"); 
       var newObj = {"sort":Cattr,"value":cValue}; 
       boxarray.push(newObj); 
      }); 
      boxarray.sort(srt({key:'sort',string:true},true)); 
      console.log(boxarray); 
      var optionsString = ""; 
      for(i=0;i<boxarray.length;i++){ 
       optionsString+= '<option data-sort="'+boxarray[i].sort+'">'+boxarray[i].value+'</option>'; 
      } 
      console.log(optionsString); 
      document.getElementById("selectbox").innerHTML = ""; 
      document.getElementById("selectbox").innerHTML = optionsString; 
     }); 

код перо URL: http://codepen.io/naveenkumarpg/pen/emBdgV/

Надеюсь, это может вам помочь.

0

Как говорили другие, это было бы лучше, если бы было сделано на стороне сервера, тем более что пользователь может отключить javascript.

Но этот пример предполагает, что выбор уже заполнен, и он перестраивает список выбора по желанию (demo):

var indx, 
    xref = {}, 
    newHtml = '', 
    $select = $('select'), 
    opts = $select.find('option') 
    // build array of options & count repeats 
    .map(function() { 
     var v = this.value; 
     if (xref[v]) { 
      xref[v]++ 
     } else { 
      xref[v] = 1; 
     } 
     return v; 
    }) 
    // sort options by adding "0" or "1" in front 
    // to perform a weighted sort so duplicates get sorted first 
    .sort(function(a, b){ 
     var x = xref[a] > 1 ? '0' + a : '1' + a, 
      y = xref[b] > 1 ? '0' + b : '1' + b; 
     return x === y ? 0 : x > y ? 1 : -1; 
    }), 
    // return unique array values 
    arr = $.grep(opts, function (v, k) { 
     return $.inArray(v, opts) === k; 
    }); 

// replace current options with new list 
for (indx = 0; indx < arr.length; indx++) { 
    newHtml += '<option value="' + arr[indx] + '">' + arr[indx] + '</option>'; 
} 
$select.html(newHtml); 
Смежные вопросы