У меня есть список задач, которые могут иметь 4 возможных состояния, взятых из объекта json.
"Not Done", "Done", "Doing", "Later"
Эти состояния хранятся в объекте, который в основном загружается через json.
var states = { status: ['doing','done', 'later' ] };
Задачи загружаются из другого объекта json.
var tasks = [
{id: 1, text: 'Do something.', status: 'doing'},
{id: 2, text: 'Undo that thing.', status: 'done'},
{id: 3, text: 'Redo it again.', status: 'started'},
{id: 4, text: 'Responsive', status:'later'}
];
Html будет что-то вроде этого.
<ul>
<li><a href="#1">Do something - <span class="status">Doing</span> </a></li>
<li><a href="#2">Undo that thing - <span class="status">Done</span> </a></li>
<li><a href="#2">Redo it again. - <span class="status">Started</span> </a></li>
</ul>
Каждый раз, когда пользователь нажимает на ссылку, статус должен переключать значение из объекта состояний и перемещаться по ним. Например, при использовании щелкните по заданию с status Done
, его нужно будет later
а когда он снова щелкнет, он должен стать Not Done
. Это должно продолжаться циклически каждый раз, когда пользователь нажимает.
Каков наилучший способ сделать это. Я чувствовал, что если иначе не будет подходящего способа сделать так, как если бы значения состояний увеличивались или уменьшались, этот код снова должен был вернуться.
Я не понял 100% вашего вопроса. Но я думаю, что сейчас. Вы хотите, чтобы код работал даже во всех случаях в любое время. Теперь я сделал код более безопасным:
Здесь взрыв кода, я немного устал, поэтому вам может понадобиться реорганизовать некоторые части. Также подумал, что вам будет легче с документацией.
Если у вас есть что сказать, оставьте это в комментариях, и я попробую еще раз....!
Рабочий jsfiddle: http://jsfiddle.net/kychan/62sUX/2/
//
// Retrieve the data with $.get()/AJAX or with an inline
// echo through PHP/ASP.
//
// Get states. Make the code extra fuzzy.
var states = { status: ['doing','dOne', 'Later' ] };
// Get the tasks.
// In this example we do it more quickly.
var tasks = [
{id: 1, text: 'Do something.', status: 'doing'},
{id: 2, text: 'Undo that thing.', status: 'done'},
{id: 3, text: 'Redo it again.', status: 'started'},
{id: 4, text: 'Responsive', status: 'later'}
];
// prepare the retrieved JSON data for fuzzy input.
states.status.forEach(function(e,i,a) {
states.status[i]=e.toUpperCase();
});
tasks.forEach(function(e,i,a) {
tasks[i].status=e.status.toUpperCase();
});
// create the li's.
for (var i in tasks) {
var item = '<li>'
+ '<a href="#" id="{id}">{text} - '
+ '<span class="status">{status}</span>'
+ '</a>'
+ '</li>'
;
item = item.replace(/{(\w+)}/g, function (m, n) {
return (typeof (tasks[i][n]) !== 'undefined') ? tasks[i][n] : '';
});
$('ul').append(item);
}
// Override the states with the button; will make it harder
// for the code and test it for future proofness.
$('.replace').click(function() {
// we will keep 'done' for testing.
states = {
status:['CONCEPT', 'ELABORATION', 'CONSTRUCTION', 'TESTING', 'PRODUCTION', 'DONE']
};
// remove the replace link, because after press it useless.
$('.replace').detach();
});
//
// actual code.
//
// create listeners on the a tags of tag ul.
$('ul a').click(function (e) {
// fetch status DOM object and its text before.
var status = $(this).children('.status');
var text = status.html();
// iterate through states array.
for (var i in states.status) {
// if the task matches your text, then update it to the next.
if (text==states.status[i]) {
// get next status.
if ((i++)>=states.status.length-1) i=0;
// update. Don't forget to push the update to the database.
status.html(states.status[i]);
return;
}
}
// state not found. reset it to first. Don't forget to push the update to the DB.
status.html(states.status[0]);
});
Как насчет чего-то подобного?
$('a').click(function(){
var id = parseInt($(this).attr('href').substring(1));
var task = tasks.filter(function(t){t.id == id});
if (task.length) {
var status = task[0].status;
var indexStatus = states.status.indexOf(status);
var nextStatus = null;
if (indexStatus === states.status.length-1) {
nextStatus = states.status[0];
} else if (indexStatus !== -1) {
nextStatus = states.status[indexStatus+1];
}
if (nextStatus !== null) {
task[0].status = nextStatus;
$(this).children('.status').text(nextStatus);
}
}
});
Идея состоит в том, чтобы искать текущий статус в списке и просто переустанавливать индекс на 0, если он последний, иначе увеличивайте его.
Я обновил JSON и HTML, так как вы не уточнили, хотите ли вы их синхронизировать. Код можно упростить, если вам не нужно синхронизировать данные и просматривать. Кроме того, я сделал все необходимые связанные проверки, я не знаю, насколько надежным вы хотите, чтобы код был и насколько вы доверяете данным json.