我有一个可以单击的编辑按钮,它将获取所需的JSON文件并将其显示在CMS端。但是,当我单击编辑功能时,一切正常,直到我添加了一个新练习。当我单击绿色+按钮时,而不是增加ID(例如,它留在2的位置,因此第三个ID应该是3)从0开始。因此,我有ID为0的双ID,以此类推上。我有一个删除按钮,应该根据其ID删除运动字段。因此,当我有两个ID均为0的运动场时,它将针对第一个运动场,而不是针对目标运动场。 它无法识别我已经具有某些ID的运动场,因此只能从ID 0开始。
看看他们两个的ID如何?
接下来我要实现的是:他们都应该保留其ID,并且每当我添加一个新的练习字段时,它们都应继续增加而不是重复ID。
我的删除按钮的外观如下:
function getRemoveBtnExercise(target, i){
var RemoveExerciseBtn = $('<a/>', {
'class': 'btn btn-danger'
}).on('click', function(){
console.log($('.eblock').prop('id'))
$('#' + target).remove();
}).html('<i class="fa fa-close"></i>');
return RemoveExerciseBtn;
}
电子锁的外观:
function getExerciseBlock(i, data){
var eBlock = $('<div/>',{
'id': i,
'class': 'col-md-6 eBlock well'
});
data = data || {
word: '',
syllables: ['','','','']
};
console.log(data.syllables);
$(eBlock).append(
getRemoveBtnExercise(i),
getAudioBtn(i),
getWordInput(i, data.word),
getWordPartInput(i, data.syllables)
);
return eBlock;
}
如果这是有用的代码,新练习字段的绿色添加按钮的方式为:
$(document).ready(function() {
var id = 0;
var addOpdracht = $('<a/>', {
'class': 'btn btn-success',
'id': 'addOpdracht'
}).on('click', function() {
$('#my_form').append(getExerciseBlock(id));
$(".exerciseGetWordInput_" + id).focus().select();
id++;
exerciseAudioInput++;
}).html('<i class="fa fa-plus fa-2x"></i>');
$('#my_form').append(addOpdracht);
$('#my_form').append(getExerciseTitle());
});
答案 0 :(得分:0)
您可以只生成一个唯一的字符串,例如使用Math.random()
(其结果是这样的:0.1459432599412
),然后在base64中对其进行编码以使其成为合法的html id。
function generateId() {
}
当然并不能保证唯一,但是完全不可能。
PS:如果需要进一步访问这些ID,可以将其封装在一个专用对象中,该对象可以生成新ID,并允许您获取旧ID。
class Identifiers {
construct() {
this.ids = [];
}
getNext() {
const id = this.getRandomId();
this.ids.push(id);
return id;
}
getRandomId() {
return btoa(Math.random());
}
getId(id) {
return this.ids.indexOf(id);
}
}
您可以像这样使用它
const ids = new Identifiers();
const first = ids.getNext(); // MC41MjQyMTE5MTMyNDIyOTY0
const second = ids.getNext(); // MC41NzI4MTk3MjE2MjU3NjYy
// ...
ids.getId(first); // 0 (because it was first)
答案 1 :(得分:0)
在上面的快照中,您是否已使用javascript代码添加了所有三个练习,或者前两个已预先添加,并且您使用了javascript添加了第三个练习?
因为在这种情况下,它将仅从id = 0
开始,因此您必须从id
开始算一号再加上已经可用的练习次数。
更新:
假设您将练习保留在div
标记中,并带有class="exercise-box"
页面加载时,您有5个练习,
<div class="exercise-box">...</div>
<div class="exercise-box">...</div>
<div class="exercise-box">...</div>
<div class="exercise-box">...</div>
<div class="exercise-box">...</div>
然后,如果您使用的是jQuery,则可以在JavaScript代码中添加以下内容,
var numItems = $('div.exercise-box').length;
然后初始化您的var id = numItems + 1;
并保留其余代码。
看到您的代码,您可以使用eBlock
代替exercise-box
,因为您已经将该类包含在div
中。
答案 2 :(得分:0)
将其存储在包装器中,也许每次都增加它。
原始编辑:
$(document).ready(function() {
// get a reference to the form cache that to avoid multiple DOM hits
var myform = $('#my_form');
// this stores the value, I assume none existed before here...
myform.data("myid",0);
var addOpdracht = $('<a/>', {
'class': 'btn btn-success',
'id': 'addOpdracht'
}).on('click', function() {
// get last the stored value on the click event
var id = $('#my_form').data("myid");
$('#my_form').append(getExerciseBlock());
$(".exerciseGetWordInput_" + id).focus().select();
exerciseAudioInput++;
}).html('<i class="fa fa-plus fa-2x"></i>');
myform.append(addOpdracht);
myform.append(getExerciseTitle());
});
function getExerciseBlock(data){
// get the last stored value and add 1 to it
var myid = $('#my_form').data("myid") + 1;
// store the new value back in there.
$('#my_form').data("myid",myid )
var eBlock = $('<div/>',{
'id': myid,
'class': 'col-md-6 eBlock well'
});
data = data || {
word: '',
syllables: ['','','','']
};
console.log(data.syllables);
$(eBlock).append(
getRemoveBtnExercise(myid),
getAudioBtn(myid),
getWordInput(myid, data.word),
getWordPartInput(myid, data.syllables)
);
return eBlock;
}
我添加了这个CRUD示例以使您入门,但并不完美,也不是您拥有的100%(我对某些事情不了解),但是可以通过按钮向列表中添加,删除,编辑行)
$(document).ready(function() {
// create row on startup
let newdata = {
name: "name-ready",
title: "Titlenew",
audio: "Pete Sings the blues"
};
addNewRow(newdata);
});
$('#editor')
.on('click', '.addnew', function(event) {
let ed = $(event.delegateTarget);
let newdata = getCurrentValues(ed);
addNewRow(newdata);
})
.on('click', '.removeme', function(event) {
alert('I would call some remove thing');
})
.on('click', '.saveme', function(event) {
let ed = $(event.delegateTarget);
ed.find('.showediting').addClass('disabled');
let id = saveEditRow(ed);
// alert('I would save somewhere id:' + id);
})
.on('click', '.clearme', function(event) {
let ed = $(event.delegateTarget);
let storeFirst = true;
clearValues(ed, storeFirst);
})
.on('click', '.cancelme', function(event) {
let ed = $(event.delegateTarget);
restoreValues(ed);
let row = $('#exercises').find('.row.edit-active');
row.removeClass('edit-active');
});
$('#exercises')
.on('displaydata', '.row.eBlock', function() {
let data = $(this).data('rowdata');
$(this).find('.title').html(data.title);
$(this).find('.name').text(data.name);
//TODO: $(this).find('.audio').text(data.audio);
});
function saveEditRow(ed) {
let data = getCurrentValues(ed);
restoreValues(ed);
// console.log(data);
let row = $('#exercises').find('.row.eBlock.edit-active');
data.rowid = row.data('rowid');
row.removeClass('edit-active');
row.data('rowdata', data);
row.trigger('displaydata');
return data.rowid;
}
function getCurrentValues(ed) {
let currentdata = {
name: ed.find('.editname').val(),
title: ed.find('.edittitle').val(),
audio: ed.find('.editaudio').val()
};
return currentdata;
}
function getRowValues(ed, row) {
let currentdata = row.data('rowdata');
return currentdata;
}
function storeValues(ed) {
let en = ed.find('.editname');
let et = ed.find('.edittitle');
let ea = ed.find('.editaudio');
en.data('lastvalue', en.val());
et.data('lastvalue', et.val());
ea.data('lastvalue', ea.val());
}
function setValues(ed, data) {
let en = ed.find('.editname');
let et = ed.find('.edittitle');
let ea = ed.find('.editaudio');
en.val(data.name);
et.val(data.title);
ea.val(data.audio);
}
function restoreValues(ed) {
let en = ed.find('.editname');
let et = ed.find('.edittitle');
let ea = ed.find('.editaudio');
en.val(en.data('lastvalue'));
et.val(et.data('lastvalue'));
ea.val(ea.data('lastvalue'));
}
function clearValues(ed, storeFirst = true) {
if (storeFirst) {
storeValues(ed);
}
let en = ed.find('.editname');
let et = ed.find('.edittitle');
let ea = ed.find('.editaudio');
en.val('');
et.val('');
ea.val('');
}
function addNewRow(data) {
let exercises = $('#exercises');
let rowId = exercises.data("excersiseid") + 1;
exercises.data("excersiseid", rowId);
data.rowid = rowId;
let igp = $("<div class='input-group-prepend' />");
let iga = $("<div class='input-group-append' />");
let addColumns = 5;
let row = newRowGroup(rowId, addColumns);
row.data("rowdata", data);
row.find('.eItem').first()
.removeClass('col').wrap(igp)
.html(getEditBtnExercise(rowId, data));
row.find('.eItem').eq(1)
.html(getExerciseName(rowId, data.name));
row.find('.eItem').eq(2)
.html(getExerciseTitle(rowId, data.title));
row.find('.eItem').eq(3)
.removeClass('col').wrap(iga)
.html(getAudioBtn(rowId, data.audio));
row.find('.eItem').last()
.removeClass('col').wrap(iga)
.html(getRemoveBtnExercise(rowId));
exercises.append(row);
}
function getExerciseTitle(rowId, title) {
var titleEl = $('<span/>', {
'class': 'title row-title'
}).on('click', function() {
var id = $(this).closest('.row.eBlock')
.data('rowid');
}).text(title);
return titleEl;
}
function getExerciseName(rowId, name) {
var nameEl = $('<span/>', {
'class': 'name row-name'
}).on('click', function() {
var id = $(this).closest('.row.eBlock')
.data('rowid');
}).text(name);
return nameEl;
}
function newRowGroup(rowid, addColumnsCount, addClasses = false) {
let eBlock = $('<div/>', {
class: 'row eBlock well input-group ',
id: 'eblock-' + rowid
}).data("rowgroupid", rowid);
// create column we will clone and add to row
let colcls = 'eItem ';
if (addClasses) {
colcls = colcls + 'col-md';
}
let props = {
class: colcls,
text: ""
};
let newcol = getCol(props);
for (var c = 0; c < addColumnsCount; c++) {
newcol.clone().appendTo(eBlock);
}
return eBlock;
}
function getCol(props) {
let newcol = $('<div></div>', {
class: 'col'
})
.addClass(props.class)
.text(props.text);
return newcol;
}
$('#addnew').on('click', function() {});
function getEditBtnExercise(rowId, data) {
var edit = $('<button/>', {
'class': 'btn btn-success btn-sm editrow',
'id': 'edit_' + rowId
});
edit.on('click', function() {
let row = $(this).closest('.row.eBlock');
row.addClass('edit-active');
let id = $(this).data('rowid');
let editor = $('#editor');
storeValues(editor);
editor.find('.showediting').removeClass('disabled');
let data = row.data('rowdata');
setValues(editor, data);
// console.log(data);
}).html('<i class="fa fa-edit fa-2x"></i>');
edit.data('rowid', rowId);
return edit;
}
function getRemoveBtnExercise(myid) {
var removeOpdracht = $('<button/>', {
'class': 'btn btn-danger btn-sm',
'id': 'removeOpdracht_' + myid
}).on('click', function() {
$(this).closest('.row').remove();
}).html('<i class="fa fa-minus fa-2x"></i>');
return removeOpdracht;
}
function getExerciseBlock(data) {
var exercises = $('#exercises');
var myid = exercises.data("excersiseid") + 1;
$('#exercises').data("myid", myid);
let eBlock = $('<div/>', {
'id': "eblock-" + myid,
'class': 'container eBlock well'
});
data = data || {
word: '',
syllables: ['', '', '', '']
};
eBlock.append(
getRemoveBtnExercise(myid),
getAudioBtn(myid),
getWordInput(myid, data.word),
getWordPartInput(myid, data.syllables)
);
return eBlock;
}
function getAudioBtn(myid, audioname) {
var audio = $('<button/>', {
'class': 'btn btn-primary btn-sm audio row-audio',
'id': 'audio_' + myid
}).data("audioname", audioname).on('click', function() {
let audioName = $(this).data("audioname")
playAudio(audioName);
}).html('<i class="fa fa-volume-up fa-2x"></i>');
return audio;
}
function playAudio(audio) {
alert('Requested: ' + audio);
}
#exercises {
border: solid lime 1px;
}
#exercises .row {
border: solid white 2px;
}
#exercises .row.edit-active {
border: solid blue 2px;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<div class="container" id="editor">
<div class="input-group md">
<div class="input-group-prepend">
<button class="btn btn-primary btn-sm showediting disabled" type="button"><span class="fa fa-tasks"></span></button>
<button class="btn btn-success btn-sm addnew" type="button"><span class="fa fa-plus fa-2x"></span></button>
</div>
<input type="text" class="form-control editname" placeholder="" aria-label="" aria-describedby="basic-addon1" value="changeme name">
<input type="text" class="form-control edittitle" placeholder="" aria-label="" aria-describedby="basic-addon1" value="New Title">
<input type="text" class="form-control editaudio" placeholder="" aria-label="" aria-describedby="basic-addon1" value="Walters Blues">
<div class="input-group-append">
<button class="btn btn-warning btn-sm clearme" type="button"><span class="fa fa-eraser"/></button>
<button class="btn btn-light btn-sm cancelme" type="button"><span class="fa fa-ban"/></button>
<button class="btn btn-primary btn-sm saveme" type="button"><span class="fa fa-save"/></button>
</div>
</div>
</div>
<div class="container" id="exercises" data-excersiseid="0">
</div>
<div>
请注意,对于此功能,最好更改为使用新创建的值:因此它与新创建的值匹配-请注意,我不确定100%.exerciseGetWordInput_
类的真正含义是什么
.on('click', function() {
$('#my_form').append(getExerciseBlock());
$(".exerciseGetWordInput_" + $('#my_form').data("myid")).focus().select();
exerciseAudioInput++;
})