I need to use jQuery to add some elements dynamically. So I looked up in the internet and I found this. It is nice and working when there is plain html elements inside single quotes. I need to use razor syntax with jQuery.
I understand that jQuery is user side and razor is server side. They cannot be combined together. I am asking here because I need to know how do i achieve this.
My not working jQuery is as follows:
<script type="text/javascript">
$(document).ready(function () {
$(document).on("click", ".btnPlus", function () {
var html = '<div class="form-group">'+
'@Html.LabelFor(model => model.transaction_item, "transaction_item", htmlAttributes: new { @class = "control-label col-md-2" })'+
'<div class="col-md-4">'+
'@Html.DropDownList("transaction_item", null, htmlAttributes: new { @class = "form-control" })'+
'@Html.ValidationMessageFor(model => model.transaction_item, "", new { @class = "text-danger" })'+
'</div>'+
'<div class="col-md-6"><input type="button" class="BtnPlus" value="+" /></div>'+
'</div>'
$("#trItem").append($(html))
};
});
My aim is similar to the tutorial - to add elements dynamically. Here I am adding a label and dropdown on the click of button. How do I achieve this?
You cannot add Razor elements using JQuery because, as you have stated, JQuery is a client side library and ASP.NET using Razor syntax is a server side scripting language.
If you want to add elements created using Razor syntax then add a hidden element to the page and use JQuery to add a clone of it to the DOM.
Something like this should give you an idea of what I mean:
@Html.DropDownList("transaction_item", null, htmlAttributes: new { @class = "form-control", @id = 'template-ddl' })
$("#trItem").append($('#template-ddl').clone());
You can create a partial page _MyPartial.cshtml
in your Views Shared folder.
Then in your view reference add the reference to your scripts section
@section Scripts {
@Html.Partial("~/Views/Shared/_MyPartial.cshtml",Model);
}
Partial page: _MyPartial.cshtml
@model MyViewModel
<script type="text/javascript">
$(document).ready(function () {
$(document).on("click", ".btnPlus", function () {
var html = '<div class="form-group">'+
'@(Html.LabelFor(model => model.transaction_item, "transaction_item", htmlAttributes: new { @class = "control-label col-md-2" }))'+
'<div class="col-md-4">'+
'@(Html.DropDownList("transaction_item", null, htmlAttributes: new { @class = "form-control" }))'+
'@(Html.ValidationMessageFor(model => model.transaction_item, "", new { @class = "text-danger" }))'+
'</div>'+
'<div class="col-md-6"><input type="button" class="BtnPlus" value="+" /></div>'+
'</div>'
$("#trItem").append($(html))
};
</script>
It is best to avoid generating jQuery/Javascript code with Razor. For many reasons your Javascript/jQuery code is better off in separate files (VS debugging/script bundling etc)
Instead inject the templated HTML into a hidden part of the page. A dummy script block works great for this as the browser will just ignore an unknown script type:
<script id="template" type="text/template">
<div class="form-group">
@Html.LabelFor(model => model.transaction_item, "transaction_item", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-4">
@Html.DropDownList("transaction_item", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.transaction_item, "", new { @class = "text-danger" })
</div>
<div class="col-md-6"><input type="button" class="BtnPlus" value="+" /></div>
</div>
</script>
You can see what is generated with your DOM inspector to ensure the correct attributes are present.
Then simply use that HTML from the template to add new buttons:
$("#trItem").append($('#template').html());
The only issue you need to resolve is any duplicate IDs and indexing for multiple items. I usually use raw HTML in the template (not Razor) and use placeholders for the various attributes that need renaming.
e.g.
<script id="template" type="text/template">
<div class="form-group">
<label for="{id}"/>