Appending html create inputs with different order
I have a html with three inputs like:
Html:
<div class="form-group" id="item-list0">
<label>Role Name</label>
<input asp-for="RoleClaimList[0].Role.Name" class="form-control roles" />
<div id="claim-list0">
<label>Claim Type</label>
<input asp-for="RoleClaimList[0].ClaimList[0].Type" class="form-control claimType" />
<label>Claim Value</label>
<input asp-for="RoleClaimList[0].ClaimList[0].Value" class="form-control claimValue" />
</div>
<a href="#" id="addClaim">Add another claim</a>
</div>
<a href="#" id="add">Add another role</a>
As you can see I have two actions "Add another role" and "Add another claim"
If I press add another claim it just replicate Claim Type
and Claim Value
inputs
If I press "Add another role" it add all inputs again
I achieve that with Jquery as:
<script>
$(function ()
var roleIndex = 0;
var claimIndex = 0;
$("#add").click(function (e)
e.preventDefault();
roleIndex = roleIndex + 1;
claimIndex = 0;
var n = '<div id="item-list' + roleIndex +'"><label>Role Name</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].Role.Name" /></div>'
var m = '<div id="claim-list' + roleIndex+'"><label>Claim Type</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Type" />'
var c = '<label>Claim Value</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Value" /> </div>'
$("#item-list" + (roleIndex - 1) + "").append(n);
$("#claim-list" + (roleIndex - 1) + "").append(m);
$("#claim-list" + (roleIndex - 1) + "").append(c);
);
$("#addClaim").click(function (e)
e.preventDefault();
claimIndex = claimIndex + 1;
var m = '<div id="claim-list' + claimIndex + '"><label>Claim Type</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Type" />'
var c = '<label>Claim Value</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Value" /> </div>'
$("#claim-list" + (claimIndex - 1) + "").append(m);
$("#claim-list" + (claimIndex - 1) + "").append(c);
);
);
</script>
If I add claim it works correctly. Problem start when I add a new role. It should replicate first tree inputs in same order of first one, but it is creating Claim Type
first then Claim Value
and finally Role Name
as this picture:
What I'm doing wrong there? Regards
jquery html5
add a comment |
I have a html with three inputs like:
Html:
<div class="form-group" id="item-list0">
<label>Role Name</label>
<input asp-for="RoleClaimList[0].Role.Name" class="form-control roles" />
<div id="claim-list0">
<label>Claim Type</label>
<input asp-for="RoleClaimList[0].ClaimList[0].Type" class="form-control claimType" />
<label>Claim Value</label>
<input asp-for="RoleClaimList[0].ClaimList[0].Value" class="form-control claimValue" />
</div>
<a href="#" id="addClaim">Add another claim</a>
</div>
<a href="#" id="add">Add another role</a>
As you can see I have two actions "Add another role" and "Add another claim"
If I press add another claim it just replicate Claim Type
and Claim Value
inputs
If I press "Add another role" it add all inputs again
I achieve that with Jquery as:
<script>
$(function ()
var roleIndex = 0;
var claimIndex = 0;
$("#add").click(function (e)
e.preventDefault();
roleIndex = roleIndex + 1;
claimIndex = 0;
var n = '<div id="item-list' + roleIndex +'"><label>Role Name</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].Role.Name" /></div>'
var m = '<div id="claim-list' + roleIndex+'"><label>Claim Type</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Type" />'
var c = '<label>Claim Value</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Value" /> </div>'
$("#item-list" + (roleIndex - 1) + "").append(n);
$("#claim-list" + (roleIndex - 1) + "").append(m);
$("#claim-list" + (roleIndex - 1) + "").append(c);
);
$("#addClaim").click(function (e)
e.preventDefault();
claimIndex = claimIndex + 1;
var m = '<div id="claim-list' + claimIndex + '"><label>Claim Type</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Type" />'
var c = '<label>Claim Value</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Value" /> </div>'
$("#claim-list" + (claimIndex - 1) + "").append(m);
$("#claim-list" + (claimIndex - 1) + "").append(c);
);
);
</script>
If I add claim it works correctly. Problem start when I add a new role. It should replicate first tree inputs in same order of first one, but it is creating Claim Type
first then Claim Value
and finally Role Name
as this picture:
What I'm doing wrong there? Regards
jquery html5
Consider how your logic is using bothroleIndex
andclaimIndex
to determine which#claim-list
to append to. You're going to be duplicating claim-list ids
– Taplar
Nov 12 '18 at 23:33
add a comment |
I have a html with three inputs like:
Html:
<div class="form-group" id="item-list0">
<label>Role Name</label>
<input asp-for="RoleClaimList[0].Role.Name" class="form-control roles" />
<div id="claim-list0">
<label>Claim Type</label>
<input asp-for="RoleClaimList[0].ClaimList[0].Type" class="form-control claimType" />
<label>Claim Value</label>
<input asp-for="RoleClaimList[0].ClaimList[0].Value" class="form-control claimValue" />
</div>
<a href="#" id="addClaim">Add another claim</a>
</div>
<a href="#" id="add">Add another role</a>
As you can see I have two actions "Add another role" and "Add another claim"
If I press add another claim it just replicate Claim Type
and Claim Value
inputs
If I press "Add another role" it add all inputs again
I achieve that with Jquery as:
<script>
$(function ()
var roleIndex = 0;
var claimIndex = 0;
$("#add").click(function (e)
e.preventDefault();
roleIndex = roleIndex + 1;
claimIndex = 0;
var n = '<div id="item-list' + roleIndex +'"><label>Role Name</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].Role.Name" /></div>'
var m = '<div id="claim-list' + roleIndex+'"><label>Claim Type</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Type" />'
var c = '<label>Claim Value</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Value" /> </div>'
$("#item-list" + (roleIndex - 1) + "").append(n);
$("#claim-list" + (roleIndex - 1) + "").append(m);
$("#claim-list" + (roleIndex - 1) + "").append(c);
);
$("#addClaim").click(function (e)
e.preventDefault();
claimIndex = claimIndex + 1;
var m = '<div id="claim-list' + claimIndex + '"><label>Claim Type</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Type" />'
var c = '<label>Claim Value</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Value" /> </div>'
$("#claim-list" + (claimIndex - 1) + "").append(m);
$("#claim-list" + (claimIndex - 1) + "").append(c);
);
);
</script>
If I add claim it works correctly. Problem start when I add a new role. It should replicate first tree inputs in same order of first one, but it is creating Claim Type
first then Claim Value
and finally Role Name
as this picture:
What I'm doing wrong there? Regards
jquery html5
I have a html with three inputs like:
Html:
<div class="form-group" id="item-list0">
<label>Role Name</label>
<input asp-for="RoleClaimList[0].Role.Name" class="form-control roles" />
<div id="claim-list0">
<label>Claim Type</label>
<input asp-for="RoleClaimList[0].ClaimList[0].Type" class="form-control claimType" />
<label>Claim Value</label>
<input asp-for="RoleClaimList[0].ClaimList[0].Value" class="form-control claimValue" />
</div>
<a href="#" id="addClaim">Add another claim</a>
</div>
<a href="#" id="add">Add another role</a>
As you can see I have two actions "Add another role" and "Add another claim"
If I press add another claim it just replicate Claim Type
and Claim Value
inputs
If I press "Add another role" it add all inputs again
I achieve that with Jquery as:
<script>
$(function ()
var roleIndex = 0;
var claimIndex = 0;
$("#add").click(function (e)
e.preventDefault();
roleIndex = roleIndex + 1;
claimIndex = 0;
var n = '<div id="item-list' + roleIndex +'"><label>Role Name</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].Role.Name" /></div>'
var m = '<div id="claim-list' + roleIndex+'"><label>Claim Type</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Type" />'
var c = '<label>Claim Value</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Value" /> </div>'
$("#item-list" + (roleIndex - 1) + "").append(n);
$("#claim-list" + (roleIndex - 1) + "").append(m);
$("#claim-list" + (roleIndex - 1) + "").append(c);
);
$("#addClaim").click(function (e)
e.preventDefault();
claimIndex = claimIndex + 1;
var m = '<div id="claim-list' + claimIndex + '"><label>Claim Type</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Type" />'
var c = '<label>Claim Value</label><input class="form-control" name="RoleClaimList[' + roleIndex + '].ClaimList[' + claimIndex + '].Value" /> </div>'
$("#claim-list" + (claimIndex - 1) + "").append(m);
$("#claim-list" + (claimIndex - 1) + "").append(c);
);
);
</script>
If I add claim it works correctly. Problem start when I add a new role. It should replicate first tree inputs in same order of first one, but it is creating Claim Type
first then Claim Value
and finally Role Name
as this picture:
What I'm doing wrong there? Regards
jquery html5
jquery html5
asked Nov 12 '18 at 22:55
JonathanJonathan
1897
1897
Consider how your logic is using bothroleIndex
andclaimIndex
to determine which#claim-list
to append to. You're going to be duplicating claim-list ids
– Taplar
Nov 12 '18 at 23:33
add a comment |
Consider how your logic is using bothroleIndex
andclaimIndex
to determine which#claim-list
to append to. You're going to be duplicating claim-list ids
– Taplar
Nov 12 '18 at 23:33
Consider how your logic is using both
roleIndex
and claimIndex
to determine which #claim-list
to append to. You're going to be duplicating claim-list ids– Taplar
Nov 12 '18 at 23:33
Consider how your logic is using both
roleIndex
and claimIndex
to determine which #claim-list
to append to. You're going to be duplicating claim-list ids– Taplar
Nov 12 '18 at 23:33
add a comment |
1 Answer
1
active
oldest
votes
What's wrong is that you are appending your new #item-list1
div into the existing #item-list0
, making it a nested structure.
Same goes to your #claim-list
, it became a nested structure:
#item-list0
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
⤷ #claim-list3
⤷ #item-list1
⤷ #item-list2
⤷ #item-list3
What you should do instead is to append them outside:
- Append new
#item-listx
to<body></body>
or whatever parent element. - Append new
#claim-list
to its corresponding#item-list
s.
So it would be your intended structure:
#item-list0
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
#item-list1
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
And if you look at it, there comes a few more problems with your code:
- You will have duplicated
id
. claimIndex
will not work properly because you reset it every time#add
is clicked (what happens if I click "addClaim" to previous roles after I add new role?)
Below is a sample code that works properly (I think, may not actually be your use case). I have restructured it so that it can be easily understood without much explanation. Please edit as needed to suit your actual code base:
var roleIndex = 0;
$('#add')
.on('click', addRole) // Add onclick handler
.trigger('click'); // Trigger it on execution to create the first set
function addRole()
roleIndex += 1;
// Set `claimIndex` here, not outside of the scope
// because you need it in each separate added role
// so that the claimIndex of each role can correctly counts independently
var claimIndex = 0,
roleClaimList = 'RoleClaimList[' + roleIndex + ']';
var $itemList = $('<div></div>')
.addClass('form-group')
.attr('id', 'item-list-' + roleIndex);
var $roleLabel = $('<label></label>')
.text('Role Name')
.appendTo($itemList);
var $roleInput = $('<input>')
.addClass('form-control roles')
.attr('asp-for', roleClaimList + '.Role.Name')
.appendTo($itemList);
var $addClaimButton = $('<a></a>')
.text('Add another claim')
.attr('href', '#')
.addClass('addClaim')
.on('click', addClaim)
.appendTo($itemList);
$addClaimButton.trigger('click');
$itemList.insertBefore(this);
// Create this function here, not outside
// because it needs the `claimIndex` in scope
function addClaim(e)
e.preventDefault();
claimIndex += 1;
var $claimGroup = $('<div></div>')
.attr('id', 'claim-list-' + roleIndex + '-' + claimIndex)
.insertBefore($addClaimButton);
var $typeLabel = $('<label></label')
.text('Claim Type')
.appendTo($claimGroup);
var $typeInput = $('<input>')
.addClass('form-control claimType')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Type')
.appendTo($claimGroup);
var $valueLabel = $('<label></label')
.text('Claim Value')
.appendTo($claimGroup);
var $valueInput = $('<input>')
.addClass('form-control claimValue')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Value')
.appendTo($claimGroup);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group" id="item-list-0"></div>
<a href="#" id="add">Add another role</a>
To know more about scoping, read this amazing answer.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53271285%2fappending-html-create-inputs-with-different-order%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
What's wrong is that you are appending your new #item-list1
div into the existing #item-list0
, making it a nested structure.
Same goes to your #claim-list
, it became a nested structure:
#item-list0
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
⤷ #claim-list3
⤷ #item-list1
⤷ #item-list2
⤷ #item-list3
What you should do instead is to append them outside:
- Append new
#item-listx
to<body></body>
or whatever parent element. - Append new
#claim-list
to its corresponding#item-list
s.
So it would be your intended structure:
#item-list0
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
#item-list1
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
And if you look at it, there comes a few more problems with your code:
- You will have duplicated
id
. claimIndex
will not work properly because you reset it every time#add
is clicked (what happens if I click "addClaim" to previous roles after I add new role?)
Below is a sample code that works properly (I think, may not actually be your use case). I have restructured it so that it can be easily understood without much explanation. Please edit as needed to suit your actual code base:
var roleIndex = 0;
$('#add')
.on('click', addRole) // Add onclick handler
.trigger('click'); // Trigger it on execution to create the first set
function addRole()
roleIndex += 1;
// Set `claimIndex` here, not outside of the scope
// because you need it in each separate added role
// so that the claimIndex of each role can correctly counts independently
var claimIndex = 0,
roleClaimList = 'RoleClaimList[' + roleIndex + ']';
var $itemList = $('<div></div>')
.addClass('form-group')
.attr('id', 'item-list-' + roleIndex);
var $roleLabel = $('<label></label>')
.text('Role Name')
.appendTo($itemList);
var $roleInput = $('<input>')
.addClass('form-control roles')
.attr('asp-for', roleClaimList + '.Role.Name')
.appendTo($itemList);
var $addClaimButton = $('<a></a>')
.text('Add another claim')
.attr('href', '#')
.addClass('addClaim')
.on('click', addClaim)
.appendTo($itemList);
$addClaimButton.trigger('click');
$itemList.insertBefore(this);
// Create this function here, not outside
// because it needs the `claimIndex` in scope
function addClaim(e)
e.preventDefault();
claimIndex += 1;
var $claimGroup = $('<div></div>')
.attr('id', 'claim-list-' + roleIndex + '-' + claimIndex)
.insertBefore($addClaimButton);
var $typeLabel = $('<label></label')
.text('Claim Type')
.appendTo($claimGroup);
var $typeInput = $('<input>')
.addClass('form-control claimType')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Type')
.appendTo($claimGroup);
var $valueLabel = $('<label></label')
.text('Claim Value')
.appendTo($claimGroup);
var $valueInput = $('<input>')
.addClass('form-control claimValue')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Value')
.appendTo($claimGroup);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group" id="item-list-0"></div>
<a href="#" id="add">Add another role</a>
To know more about scoping, read this amazing answer.
add a comment |
What's wrong is that you are appending your new #item-list1
div into the existing #item-list0
, making it a nested structure.
Same goes to your #claim-list
, it became a nested structure:
#item-list0
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
⤷ #claim-list3
⤷ #item-list1
⤷ #item-list2
⤷ #item-list3
What you should do instead is to append them outside:
- Append new
#item-listx
to<body></body>
or whatever parent element. - Append new
#claim-list
to its corresponding#item-list
s.
So it would be your intended structure:
#item-list0
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
#item-list1
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
And if you look at it, there comes a few more problems with your code:
- You will have duplicated
id
. claimIndex
will not work properly because you reset it every time#add
is clicked (what happens if I click "addClaim" to previous roles after I add new role?)
Below is a sample code that works properly (I think, may not actually be your use case). I have restructured it so that it can be easily understood without much explanation. Please edit as needed to suit your actual code base:
var roleIndex = 0;
$('#add')
.on('click', addRole) // Add onclick handler
.trigger('click'); // Trigger it on execution to create the first set
function addRole()
roleIndex += 1;
// Set `claimIndex` here, not outside of the scope
// because you need it in each separate added role
// so that the claimIndex of each role can correctly counts independently
var claimIndex = 0,
roleClaimList = 'RoleClaimList[' + roleIndex + ']';
var $itemList = $('<div></div>')
.addClass('form-group')
.attr('id', 'item-list-' + roleIndex);
var $roleLabel = $('<label></label>')
.text('Role Name')
.appendTo($itemList);
var $roleInput = $('<input>')
.addClass('form-control roles')
.attr('asp-for', roleClaimList + '.Role.Name')
.appendTo($itemList);
var $addClaimButton = $('<a></a>')
.text('Add another claim')
.attr('href', '#')
.addClass('addClaim')
.on('click', addClaim)
.appendTo($itemList);
$addClaimButton.trigger('click');
$itemList.insertBefore(this);
// Create this function here, not outside
// because it needs the `claimIndex` in scope
function addClaim(e)
e.preventDefault();
claimIndex += 1;
var $claimGroup = $('<div></div>')
.attr('id', 'claim-list-' + roleIndex + '-' + claimIndex)
.insertBefore($addClaimButton);
var $typeLabel = $('<label></label')
.text('Claim Type')
.appendTo($claimGroup);
var $typeInput = $('<input>')
.addClass('form-control claimType')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Type')
.appendTo($claimGroup);
var $valueLabel = $('<label></label')
.text('Claim Value')
.appendTo($claimGroup);
var $valueInput = $('<input>')
.addClass('form-control claimValue')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Value')
.appendTo($claimGroup);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group" id="item-list-0"></div>
<a href="#" id="add">Add another role</a>
To know more about scoping, read this amazing answer.
add a comment |
What's wrong is that you are appending your new #item-list1
div into the existing #item-list0
, making it a nested structure.
Same goes to your #claim-list
, it became a nested structure:
#item-list0
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
⤷ #claim-list3
⤷ #item-list1
⤷ #item-list2
⤷ #item-list3
What you should do instead is to append them outside:
- Append new
#item-listx
to<body></body>
or whatever parent element. - Append new
#claim-list
to its corresponding#item-list
s.
So it would be your intended structure:
#item-list0
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
#item-list1
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
And if you look at it, there comes a few more problems with your code:
- You will have duplicated
id
. claimIndex
will not work properly because you reset it every time#add
is clicked (what happens if I click "addClaim" to previous roles after I add new role?)
Below is a sample code that works properly (I think, may not actually be your use case). I have restructured it so that it can be easily understood without much explanation. Please edit as needed to suit your actual code base:
var roleIndex = 0;
$('#add')
.on('click', addRole) // Add onclick handler
.trigger('click'); // Trigger it on execution to create the first set
function addRole()
roleIndex += 1;
// Set `claimIndex` here, not outside of the scope
// because you need it in each separate added role
// so that the claimIndex of each role can correctly counts independently
var claimIndex = 0,
roleClaimList = 'RoleClaimList[' + roleIndex + ']';
var $itemList = $('<div></div>')
.addClass('form-group')
.attr('id', 'item-list-' + roleIndex);
var $roleLabel = $('<label></label>')
.text('Role Name')
.appendTo($itemList);
var $roleInput = $('<input>')
.addClass('form-control roles')
.attr('asp-for', roleClaimList + '.Role.Name')
.appendTo($itemList);
var $addClaimButton = $('<a></a>')
.text('Add another claim')
.attr('href', '#')
.addClass('addClaim')
.on('click', addClaim)
.appendTo($itemList);
$addClaimButton.trigger('click');
$itemList.insertBefore(this);
// Create this function here, not outside
// because it needs the `claimIndex` in scope
function addClaim(e)
e.preventDefault();
claimIndex += 1;
var $claimGroup = $('<div></div>')
.attr('id', 'claim-list-' + roleIndex + '-' + claimIndex)
.insertBefore($addClaimButton);
var $typeLabel = $('<label></label')
.text('Claim Type')
.appendTo($claimGroup);
var $typeInput = $('<input>')
.addClass('form-control claimType')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Type')
.appendTo($claimGroup);
var $valueLabel = $('<label></label')
.text('Claim Value')
.appendTo($claimGroup);
var $valueInput = $('<input>')
.addClass('form-control claimValue')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Value')
.appendTo($claimGroup);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group" id="item-list-0"></div>
<a href="#" id="add">Add another role</a>
To know more about scoping, read this amazing answer.
What's wrong is that you are appending your new #item-list1
div into the existing #item-list0
, making it a nested structure.
Same goes to your #claim-list
, it became a nested structure:
#item-list0
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
⤷ #claim-list3
⤷ #item-list1
⤷ #item-list2
⤷ #item-list3
What you should do instead is to append them outside:
- Append new
#item-listx
to<body></body>
or whatever parent element. - Append new
#claim-list
to its corresponding#item-list
s.
So it would be your intended structure:
#item-list0
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
#item-list1
⤷ #claim-list0
⤷ #claim-list1
⤷ #claim-list2
And if you look at it, there comes a few more problems with your code:
- You will have duplicated
id
. claimIndex
will not work properly because you reset it every time#add
is clicked (what happens if I click "addClaim" to previous roles after I add new role?)
Below is a sample code that works properly (I think, may not actually be your use case). I have restructured it so that it can be easily understood without much explanation. Please edit as needed to suit your actual code base:
var roleIndex = 0;
$('#add')
.on('click', addRole) // Add onclick handler
.trigger('click'); // Trigger it on execution to create the first set
function addRole()
roleIndex += 1;
// Set `claimIndex` here, not outside of the scope
// because you need it in each separate added role
// so that the claimIndex of each role can correctly counts independently
var claimIndex = 0,
roleClaimList = 'RoleClaimList[' + roleIndex + ']';
var $itemList = $('<div></div>')
.addClass('form-group')
.attr('id', 'item-list-' + roleIndex);
var $roleLabel = $('<label></label>')
.text('Role Name')
.appendTo($itemList);
var $roleInput = $('<input>')
.addClass('form-control roles')
.attr('asp-for', roleClaimList + '.Role.Name')
.appendTo($itemList);
var $addClaimButton = $('<a></a>')
.text('Add another claim')
.attr('href', '#')
.addClass('addClaim')
.on('click', addClaim)
.appendTo($itemList);
$addClaimButton.trigger('click');
$itemList.insertBefore(this);
// Create this function here, not outside
// because it needs the `claimIndex` in scope
function addClaim(e)
e.preventDefault();
claimIndex += 1;
var $claimGroup = $('<div></div>')
.attr('id', 'claim-list-' + roleIndex + '-' + claimIndex)
.insertBefore($addClaimButton);
var $typeLabel = $('<label></label')
.text('Claim Type')
.appendTo($claimGroup);
var $typeInput = $('<input>')
.addClass('form-control claimType')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Type')
.appendTo($claimGroup);
var $valueLabel = $('<label></label')
.text('Claim Value')
.appendTo($claimGroup);
var $valueInput = $('<input>')
.addClass('form-control claimValue')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Value')
.appendTo($claimGroup);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group" id="item-list-0"></div>
<a href="#" id="add">Add another role</a>
To know more about scoping, read this amazing answer.
var roleIndex = 0;
$('#add')
.on('click', addRole) // Add onclick handler
.trigger('click'); // Trigger it on execution to create the first set
function addRole()
roleIndex += 1;
// Set `claimIndex` here, not outside of the scope
// because you need it in each separate added role
// so that the claimIndex of each role can correctly counts independently
var claimIndex = 0,
roleClaimList = 'RoleClaimList[' + roleIndex + ']';
var $itemList = $('<div></div>')
.addClass('form-group')
.attr('id', 'item-list-' + roleIndex);
var $roleLabel = $('<label></label>')
.text('Role Name')
.appendTo($itemList);
var $roleInput = $('<input>')
.addClass('form-control roles')
.attr('asp-for', roleClaimList + '.Role.Name')
.appendTo($itemList);
var $addClaimButton = $('<a></a>')
.text('Add another claim')
.attr('href', '#')
.addClass('addClaim')
.on('click', addClaim)
.appendTo($itemList);
$addClaimButton.trigger('click');
$itemList.insertBefore(this);
// Create this function here, not outside
// because it needs the `claimIndex` in scope
function addClaim(e)
e.preventDefault();
claimIndex += 1;
var $claimGroup = $('<div></div>')
.attr('id', 'claim-list-' + roleIndex + '-' + claimIndex)
.insertBefore($addClaimButton);
var $typeLabel = $('<label></label')
.text('Claim Type')
.appendTo($claimGroup);
var $typeInput = $('<input>')
.addClass('form-control claimType')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Type')
.appendTo($claimGroup);
var $valueLabel = $('<label></label')
.text('Claim Value')
.appendTo($claimGroup);
var $valueInput = $('<input>')
.addClass('form-control claimValue')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Value')
.appendTo($claimGroup);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group" id="item-list-0"></div>
<a href="#" id="add">Add another role</a>
var roleIndex = 0;
$('#add')
.on('click', addRole) // Add onclick handler
.trigger('click'); // Trigger it on execution to create the first set
function addRole()
roleIndex += 1;
// Set `claimIndex` here, not outside of the scope
// because you need it in each separate added role
// so that the claimIndex of each role can correctly counts independently
var claimIndex = 0,
roleClaimList = 'RoleClaimList[' + roleIndex + ']';
var $itemList = $('<div></div>')
.addClass('form-group')
.attr('id', 'item-list-' + roleIndex);
var $roleLabel = $('<label></label>')
.text('Role Name')
.appendTo($itemList);
var $roleInput = $('<input>')
.addClass('form-control roles')
.attr('asp-for', roleClaimList + '.Role.Name')
.appendTo($itemList);
var $addClaimButton = $('<a></a>')
.text('Add another claim')
.attr('href', '#')
.addClass('addClaim')
.on('click', addClaim)
.appendTo($itemList);
$addClaimButton.trigger('click');
$itemList.insertBefore(this);
// Create this function here, not outside
// because it needs the `claimIndex` in scope
function addClaim(e)
e.preventDefault();
claimIndex += 1;
var $claimGroup = $('<div></div>')
.attr('id', 'claim-list-' + roleIndex + '-' + claimIndex)
.insertBefore($addClaimButton);
var $typeLabel = $('<label></label')
.text('Claim Type')
.appendTo($claimGroup);
var $typeInput = $('<input>')
.addClass('form-control claimType')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Type')
.appendTo($claimGroup);
var $valueLabel = $('<label></label')
.text('Claim Value')
.appendTo($claimGroup);
var $valueInput = $('<input>')
.addClass('form-control claimValue')
.attr('asp-for', roleClaimList + '.ClaimList[' + claimIndex + '].Value')
.appendTo($claimGroup);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group" id="item-list-0"></div>
<a href="#" id="add">Add another role</a>
edited Nov 14 '18 at 1:35
answered Nov 13 '18 at 2:30
Yong QuanYong Quan
2,0591621
2,0591621
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53271285%2fappending-html-create-inputs-with-different-order%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Consider how your logic is using both
roleIndex
andclaimIndex
to determine which#claim-list
to append to. You're going to be duplicating claim-list ids– Taplar
Nov 12 '18 at 23:33