All,
I have a popup that is inserted via javascript when a button is clicked:
function loadTypeManagement(existingDocTypes) {
const typeManagementModalDiv =
'<div class="modal fade" id="typeManagementModalDiv" >' +
'<div class="modal-dialog" style="max-width: none;">' +
'<div class="modal-content feedback_popup" style="height:100%; margin-top: 0vh;">' +
'<form class="feedback_form" autocomplete="off" action="/" method="post" id="taskitem_form">' +
'<h1 id="djangoInsert">Type Management</h1><br>' +
'<hr>' +
'<div class="autocomplete container justify-content-center">' +
'<h3 style="margin-bottom: .5vw;">Add a Document Type</h3>' +
'<hr style="width: 50% ;margin: auto; margin-bottom: .5vh;">' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<label class="col-6 admin_input_desc ">Document Type:</label>' +
'<div class="col-3"></div>' +
'</div>' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<input class=" text-center col-6 admin_input " id="addDoctypeId" type="text" name="addDocTypeName" placeholder="Document Type">' +
'<div class="col-3"></div>' +
'<div class="d-inline p-2 text-white ">' +
'<p class="col-sm-4 admin_input_desc d-inline">Can this new type be an Authentication Source?</p>' +
'<label class="">No</label>' +
' <input type="radio" id="date_newToOld" name="choice" value="date_newToOld" checked/>' +
'<label class="float-right " style="margin-left: 1.25vw;">Yes</label>' +
' <input class="float-left" type="radio" id="date_newToOld" name="choice" value="date_newToOld" />' +
'</div>' +
'</div>' +
'<input class="submit_button" name="submit" type="submit" value="Add Document Type">' +
'</div>' +
'</form>' +
'<form class="feedback_form" autocomplete="on" action="/action_page.php">' +
'<hr>' +
'<div class="autocomplete container justify-content-center">' +
'<h3 style="margin-bottom: .5vw;">Remove a Document Type</h3>' +
'<hr style="width: 50% ;margin: auto; margin-bottom: .5vh;">' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<label class="col-6 admin_input_desc ">Document Type:</label>' +
'<div class="col-3"></div>' +
'</div>' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<tr>' +
'<td class=" text-center col-6 remove_doc_dropdown ">' +
'<select class=" text-center remove_doc_dropdown2 " id="m" >' +
'<option id="-1" value="" selected disabled>Document Type</option>' +
'</select>' +
'</td>' +
'</tr>' +
'<div class="col-3"></div>' +
'<div class="d-inline p-2 text-white ">' +
'</div>' +
'</div>' +
'<input class="submit_button" type="submit" value="Remove Document Type">' +
'</div>' +
'<hr>' +
'</form>' +
'<form class="feedback_form" autocomplete="on" action="/action_page.php">' +
'<div class="autocomplete container justify-content-center">' +
'<h3 style="margin-bottom: .5vw;">Change a Document Type</h3>' +
'<hr style="width: 50% ;margin: auto; margin-bottom: .5vh;">' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<label class="col-6 admin_input_desc ">Change Document Type:</label>' +
'<div class="col-3"></div>' +
'</div>' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<tr>' +
'<td class=" text-center col-6 remove_doc_dropdown ">' +
'<select class=" text-center remove_doc_dropdown2 " id="m2" >' +
'<option id="-1" value="" selected disabled>Document Type</option>' +
'</select>' +
'</td>' +
'</tr>' +
'<div class="col-3"></div>' +
'</div>' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<label class="col-6 admin_input_desc ">To Document Type:</label>' +
'<div class="col-3"></div>' +
'</div>' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<input class=" text-center col-6 admin_input " id="myInput" type="text" name="myCountry" placeholder="Document Type">' +
'<div class="col-3"></div>' +
'<div class="d-inline p-2 text-white ">' +
'</div>' +
'</div>' +
'<div class="row">' +
'<div class="col-4"></div>' +
'<input class="col-4 submit_button" type="submit" value="Change Document Type">' +
'<div class="col-4"></div>' +
'<div class="d-inline p-2 text-white ">' +
'</div>' +
'</div>' +
'<hr>' +
'</form>' +
'</div>' +
'</div>' +
'</div>';
const newDiv = document.createElement("div");
newDiv.innerHTML = typeManagementModalDiv;
var data = $('form').serialize()
document.body.appendChild(newDiv);
for (i = 0; i < existingDocTypes.length; i++) {
var opt = document.createElement("option");
document.getElementById("m").innerHTML += '<option class="option_value" value = "' + existingDocTypes[i] + '" id="' + i + '">' + existingDocTypes[i] + '</option>';
document.getElementById("m2").innerHTML += '<option class="option_value" value = "' + existingDocTypes[i] + '" id="' + i + '">' + existingDocTypes[i] + '</option>';
}
I am trying to submit the form and keep getting the error "CSRF token missing or incorrect." I've tried to insert it via string '{% csrf_token %}', but that just leaves the string value and Django doesn't pick up on it.
Any idea how I can do this? Is there a better way?
I'm not completely sure if there are any security concerns using this method (please let me know if there are), but I was able to initiate the {{ csrftoken }} within the template using:
<script>
var csrftoken = '{{ csrf_token }}';
</script>
and then passing that token value to the JS function like so:
<a onclick="loadTypeManagement({{ existingDocTypes }}, csrftoken);" id="feedbackButton" data-toggle="modal" data-target="#typeManagementModalDiv" class="hide_table_button underline_none" href="{% url 'admin:login' %}">Type Management</a>
Then, within the JS, I was able to add the line:
'<input type="hidden" name="csrfmiddlewaretoken" value="' + csrftoken + '">' +
which holds the token value.
So, the full JS looks like this:
function loadTypeManagement(existingDocTypes, csrftoken) {
console.log(csrftoken)
const typeManagementModalDiv =
'<div class="modal fade" id="typeManagementModalDiv" >' +
'<div class="modal-dialog" style="max-width: none;">' +
'<div class="modal-content feedback_popup" style="height:100%; margin-top: 0vh;">' +
'<form class="feedback_form" autocomplete="off" action="/adminFunct/" method="post" id="taskitem_form">' +
'<input type="hidden" name="csrfmiddlewaretoken" value="' + csrftoken + '">' +
'<h1 id="djangoInsert">Type Management</h1><br>' +
'<hr>' +
'<div class="autocomplete container justify-content-center">' +
'<h3 style="margin-bottom: .5vw;">Add a Document Type</h3>' +
'<hr style="width: 50% ;margin: auto; margin-bottom: .5vh;">' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<label class="col-6 admin_input_desc ">Document Type:</label>' +
'<div class="col-3"></div>' +
'</div>' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<input class=" text-center col-6 admin_input " id="addDoctypeId" type="text" name="addDocTypeName" placeholder="Document Type">' +
'<div class="col-3"></div>' +
'<div class="d-inline p-2 text-white ">' +
'<p class="col-sm-4 admin_input_desc d-inline">Can this new type be an Authentication Source?</p>' +
'<label class="">No</label>' +
' <input type="radio" id="date_newToOld" name="choice" value="date_newToOld" checked/>' +
'<label class="float-right " style="margin-left: 1.25vw;">Yes</label>' +
' <input class="float-left" type="radio" id="date_newToOld" name="choice" value="date_newToOld" />' +
'</div>' +
'</div>' +
'<input class="submit_button" name="submit" type="submit" value="Add Document Type">' +
'</div>' +
'</form>' +
'<form class="feedback_form" autocomplete="on" action="/action_page.php">' +
'<hr>' +
'<div class="autocomplete container justify-content-center">' +
'<h3 style="margin-bottom: .5vw;">Remove a Document Type</h3>' +
'<hr style="width: 50% ;margin: auto; margin-bottom: .5vh;">' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<label class="col-6 admin_input_desc ">Document Type:</label>' +
'<div class="col-3"></div>' +
'</div>' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<tr>' +
'<td class=" text-center col-6 remove_doc_dropdown ">' +
'<select class=" text-center remove_doc_dropdown2 " id="m" >' +
'<option id="-1" value="" selected disabled>Document Type</option>' +
'</select>' +
'</td>' +
'</tr>' +
'<div class="col-3"></div>' +
'<div class="d-inline p-2 text-white ">' +
'</div>' +
'</div>' +
'<input class="submit_button" type="submit" value="Remove Document Type">' +
'</div>' +
'<hr>' +
'</form>' +
'<form class="feedback_form" autocomplete="on" action="/action_page.php">' +
'<div class="autocomplete container justify-content-center">' +
'<h3 style="margin-bottom: .5vw;">Change a Document Type</h3>' +
'<hr style="width: 50% ;margin: auto; margin-bottom: .5vh;">' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<label class="col-6 admin_input_desc ">Change Document Type:</label>' +
'<div class="col-3"></div>' +
'</div>' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<tr>' +
'<td class=" text-center col-6 remove_doc_dropdown ">' +
'<select class=" text-center remove_doc_dropdown2 " id="m2" >' +
'<option id="-1" value="" selected disabled>Document Type</option>' +
'</select>' +
'</td>' +
'</tr>' +
'<div class="col-3"></div>' +
'</div>' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<label class="col-6 admin_input_desc ">To Document Type:</label>' +
'<div class="col-3"></div>' +
'</div>' +
'<div class="row">' +
'<div class="col-3"></div>' +
'<input class=" text-center col-6 admin_input " id="myInput" type="text" name="myCountry" placeholder="Document Type">' +
'<div class="col-3"></div>' +
'<div class="d-inline p-2 text-white ">' +
'</div>' +
'</div>' +
'<div class="row">' +
'<div class="col-4"></div>' +
'<input class="col-4 submit_button" type="submit" value="Change Document Type">' +
'<div class="col-4"></div>' +
'<div class="d-inline p-2 text-white ">' +
'</div>' +
'</div>' +
'<hr>' +
'</form>' +
'</div>' +
'</div>' +
'</div>';
const newDiv = document.createElement("div");
newDiv.innerHTML = typeManagementModalDiv;
document.body.appendChild(newDiv);
for (i = 0; i < existingDocTypes.length; i++) {
var opt = document.createElement("option");
document.getElementById("m").innerHTML += '<option class="option_value" value = "' + existingDocTypes[i] + '" id="' + i + '">' + existingDocTypes[i] + '</option>';
document.getElementById("m2").innerHTML += '<option class="option_value" value = "' + existingDocTypes[i] + '" id="' + i + '">' + existingDocTypes[i] + '</option>';
}
For any curious, this portion is used for dropdown stuff and not needed for anything related to the csrf_token
for (i = 0; i < existingDocTypes.length; i++) {
var opt = document.createElement("option");
document.getElementById("m").innerHTML += '<option class="option_value" value = "' + existingDocTypes[i] + '" id="' + i + '">' + existingDocTypes[i] + '</option>';
document.getElementById("m2").innerHTML += '<option class="option_value" value = "' + existingDocTypes[i] + '" id="' + i + '">' + existingDocTypes[i] + '</option>';
}
$(function() {
$("#showMovies").click(function() {
$.ajax({
method: "GET",
url: "http://localhost:3000/movielist",
dataType: "json",
success: function(response) {
$.each(response, function(i, movie) {
const rowText = "<tr>" +
"<td>" + movie.idmovielist + "</td>" +
"<td>" + movie.name + "</td>" +
"<td>" + movie.thumbnail_path + "</td>" +
"<td>" + movie.description + "</td>" +
"<td>" + movie.year_released + "</td>" +
"<td>" + movie.language_released + "</td>" +
"<td>" + "<button button id = \"deleteMovie\" type=\"button\" class=\"btn btn-danger\" data-toggle=\"modal\" data-target=\"#exampleModal\">Delete</button>" + "</td>" +
"<td>" + "<button button id = \"editMovie\" type=\"button\" class=\"btn btn-danger\" data-toggle=\"modal\" data-target=\"#exampleModal\">Edit</button>" + "</td>";
$("#movies").append(rowText);
});
}
});
});
$("#movieAdded").click(function(a) {
let mydata = {
idmovielist: $($("#newForm")[0].intNum).val(),
name: $($("#newForm")[0].name).val(),
thumnail_path: $($("#newForm")[0].thumnail_path).val(),
description: $($("#newForm")[0].description).val(),
year_released: $($("#newForm")[0].year_released).val(),
language_released: $($("#newForm")[0].language_released).val(),
}
displayMovie(mydata);
$("#newForm").trigger("reset");
$("#newForm").toggle();
a.preventDefault();
});
function displayMovie(data) {
$.ajax({
method: "POST",
url: "http://localhost:3000/movielist/addMovie",
dataType: "json",
data: data,
success: function(data) {
console.log(data);
}
});
}
$.ajax({
method: "DELETE",
url: "http://localhost:3000/movielist/5",
dataType: "json",
success: function(data) {
$.each(data, function(i, movie) {
const rowText = "<tr>" +
"<td>" + movie.idmovielist + "</td>" +
"<td>" + movie.name + "</td>" +
"<td>" + movie.thumbnail_path + "</td>" +
"<td>" + movie.description + "</td>" +
"<td>" + movie.year_released + "</td>" +
"<td>" + movie.language_released + "</td>" +
"<td>" + "<button button id = \"deleteMovie\" type=\"button\" class=\"btn btn-danger\" data-toggle=\"modal\" data-target=\"#exampleModal\">Delete</button>" + "</td>" +
"<td>" + "<button button id = \"editMovie\" type=\"button\" class=\"btn btn-danger\" data-toggle=\"modal\" data-target=\"#exampleModal\">Edit</button>" + "</td>";
$("#movies").append(rowText);
});
}
});
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
table {
background-color: lightblue;
}
tbody {
font-family: inherit;
}
html {
background-color: lightblue;
}
#banner-message {
background: #fff;
border-radius: 4px;
padding: 20px;
font-size: 25px;
text-align: center;
transition: all 0.2s;
margin: 0 auto;
width: 300px;
}
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link href="mystyle.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/themes/smoothness/jquery-ui.css" />
<script src="mycrud.js"></script>
</head>
<body>
<title>My Movies</title>
<header>
<h1>Movies</h1>
<button id="showMovies" type="button" class="btn btn-primary" data-toggle="modal" data-target=#exampleModal>All Movies</button>
</header>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form id="newForm">
<div class="form-group row">
<label for="idmovielist" class="col-sm-2 col-form-label">idmovielist</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="intNum" placeholder="idmovielist">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-2 col-form-label">name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" placeholder="name">
</div>
</div>
<div class="form-group row">
<label for="thumnail_path" class="col-sm-2 col-form-label">thumnail_path</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="thumnail_path" placeholder="thumnail_path">
</div>
</div>
<div class="form-group row">
<label for="description" class="col-sm-2 col-form-label">description</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="description" placeholder="description">
</div>
</div>
<div class="form-group row">
<label for="year_released" class="col-sm-2 col-form-label">year_released</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="year_released" placeholder="year_released">
</div>
</div>
<div class="form-group row">
<label for="language_released" class="col-sm-2 col-form-label">language_released</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="language_released" placeholder="language_released">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button id="movieAdded" type="button" class="btn btn-primary" data-toggle="modal" data-target=#exampleModal>Add</button>
</div>
</form>
</div>
</div>
</div>
</div>
<button id="movieAdded" type="button" class="btn btn-primary" data-toggle="modal" data-target=#exampleModal>Add</button>
<table class="table table-bordered table-hover" width="100%">
<thead style="background-color:#ddd;" class="table-borderless">
<tr>
<th>idmovielist</th>
<th>name</th>
<th>thumnail_path</th>
<th>description</th>
<th>year_released</th>
<th>language_released</th>
<th>Action</th>
</tr>
</thead>
<tbody id="movies">
</tbody>
</table>
</header>
</body>
</html>
So above is my html css and java-script and also I have a screen shot of my UI I have did a post request back-end and I also executed it in the front end as well when I click the add button the modal form pops up on what things I want to add is there a way I could do a post request only on front end with out having to go back to back end and changing it every-time
app.post('/movielist/addMovie',(req, res) => {
mysqlConnection.query("INSERT INTO movielist (`idmovielist`,`name`,`thumnail_path`,`description`,`language_released`,`year_released`) VALUES ('64','DudeLove','wfburfr.jpg','silly','2019','english')",
req.body,
(err,rows) => {
if (!err) {
res.send("Movie is added");
} else {
console.log(err);
}
});
});
above is the code of my back end I did and is you see in the Ui the result is their but if I want to add more movies is there a way I could just add movies in the front end with out having to go back all the time to the back end to change it
As You are using POST method, you have to pass the params in the POST's body and read them on the serverside.
Your clientside is correct - you pass data to the server.
$.ajax({
method: "POST",
url: "http://localhost:3000/movielist/addMovie",
dataType: "json",
data: data,
success: function(data) {
console.log(data);
}
});
On the serverside you read POST body data elements using req.body.PARAMNAME;
As You've passed them as JSON, they will be parsed already.
So now you just put those values into the query dynamically:
"INSERT INTO movielist (`idmovielist`,`name`) VALUES ('"+req.body.idmovielist+"', '"+req.body.name+"')",
OF COURSE you should escape the strings for SQL injections first. And ID probably shouldn't be passed, but auto-incremented in the database.
mysqlConnection.query("INSERT INTO movielist (`idmovielist`,`name`,`thumnail_path`,`description`,`language_released`,`year_released`) VALUES ('64','DudeLove','wfburfr.jpg','silly','2019','english')",
You've hard-coded the values to be inserted into your query.
Don't do that. Read the values from the POST request.
I want to have a value in "sr.no." field that is auto incremented every time i click on button that adds new clause.
html:
<div id="clauseDiv">
<div class="col-sm-12">
<div class="col-sm-6">
<div class="form-group">
<label class="control-label col-sm-2" for="clause">Clause: </label>
<div class="col-sm-10">
<input type="text" class="form-control clauseHeader" v-bind:id="'clauseHeader-' + clause.contractGroupId"
name="clause" :key="index" v-bind:value="clause.contractGroupName" readonly="readonly"/>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label class="control-label col-sm-2" for="sequence">Sr.no.: </label>
<div class="col-sm-4">
<input type="text" class="form-control clauseSequence" v-bind:id="'clauseSequence-' + clause.contractGroupId" name="sequence"
:key="index" v-bind:value="clause.sequence" />
</div>
</div>
</div>
<div class="col-sm-12">
<div class="form-group">
<label class="control-label col-sm-1" for="subClause">Subclause: </label>
<div class="col-sm-11">
<div>
<textarea class="form-control subClause" v-bind:id="'subClause-' + clause.contractGroupId"
:key="index" readonly="readonly"></textarea>
</div>
</div>
</div>
</div>
</div>
js:
var clauseHtml = '<div class="col-sm-12" id="clause-'+this.count+'">'+
'<div class="col-sm-6">'+
'<div class="form-group">'+
' <label class="control-label col-sm-2" for="clause">Clause: </label>'+
' <div class="col-sm-10">'+
' <input type="text" class="form-control clauseAddlTermHeader" id="clauseHeader-'+this.count+'" name="clause" />'+
' </div>'+
' </div>'+
'</div>'+
'<div class="col-sm-4">'+
'<div class="form-group">'+
' <label class="control-label col-sm-2" for="sequence">Sr.no: </label>'+
' <div class="col-sm-4">'+
' <input type="text" class="form-control clauseAddlTermSequence" id="clauseSequence-'+this.count+'" name="sequence"/>'+
' </div>'+
' </div>'+
' </div>'+
'<div class="col-sm-2">'+
'<div class="form-group">'+
' <button type="button" class="btn btn-danger deleteClause" id="deleteClause-'+this.count+'" v-on:click="deleteClause">Delete</button>'+
' </div>'+
' </div>'+
'<div class="col-sm-12">'+
' <div class="form-group">'+
' <label class="control-label col-sm-1" for="subClause">Subclause: </label>'+
' <div class="col-sm-11">'+
' <textarea class="form-control clauseAddlTermSubClause" id="subClause-'+this.count+'" ></textarea>'+
' </div>'+
' </div>'+
' </div>'+
'</div>';
$('#clauseDiv').append(clauseHtml);
this.count++;
From html, I am adding div which contains 'clause', 'sr.no.' and 'subclause' fields. I have a button, and when clicked on that button the js part gets executed and the div appends and more 'clause', 'sr.no.' and 'subclause' fields are added. I want the newly appended 'sr.no' field to get a value in it that is auto incremented from the previous field. How do I do that?
remove this from this.count and make the count as global variable, add value="' + count +'" to the input and it should be like this
'<input type="text" class="form-control clauseAddlTermSequence" id="clauseSequence-' + count + '" name="sequence" value="' + count +'"/>'
Demo:
var count = 0;
$('#addClause').on('click', function() {
var clauseHtml = '<div class="col-sm-12" id="clause-' + count + '">' +
'<div class="col-sm-6">' +
'<div class="form-group">' +
' <label class="control-label col-sm-2" for="clause">Clause: </label>' +
' <div class="col-sm-10">' +
' <input type="text" class="form-control clauseAddlTermHeader" id="clauseHeader-' + count + '" name="clause" />' +
' </div>' +
' </div>' +
'</div>' +
'<div class="col-sm-4">' +
'<div class="form-group">' +
' <label class="control-label col-sm-2" for="sequence">Sr.no: </label>' +
' <div class="col-sm-4">' +
' <input type="text" class="form-control clauseAddlTermSequence" id="clauseSequence-' + count + '" name="sequence" value="' + count +'"/>' +
' </div>' +
' </div>' +
' </div>' +
'<div class="col-sm-2">' +
'<div class="form-group">' +
' <button type="button" class="btn btn-danger deleteClause" id="deleteClause-' + count + '" v-on:click="deleteClause">Delete</button>' +
' </div>' +
' </div>' +
'<div class="col-sm-12">' +
' <div class="form-group">' +
' <label class="control-label col-sm-1" for="subClause">Subclause: </label>' +
' <div class="col-sm-11">' +
' <textarea class="form-control clauseAddlTermSubClause" id="subClause-' + count + '" ></textarea>' +
' </div>' +
' </div>' +
' </div>' +
'</div>';
$('#clauseDiv').append(clauseHtml);
count++;
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addClause">addCaluse</button>
<div id="clauseDiv"></div>
I have a dynamic form for items. First row items form will appear with (+) and (-) button, next they click (+) button and (-) in the previous row and now I have problem when I want to remove row that has (+) and (-), I need to add (+) button on previous row. I read about closest and find, but I cant use it.
here is my html
var index = 1;
$(document).ready(function() {
addItems(index);
});
function addItems(index) {
$('#btn-add-item').remove();
$('#item_list').append(
"<div class='items' id='item_" + index + "'>" +
"<div class='row'>" +
"<div class='col-md-3'>" +
"<div class='form-group'>" +
"<input type='text' class='form-control' name='item_qty[]' placeholder='Item qty' data-error='Item qty cannot empty' required>" +
"<div class='help-block with-errors'></div>" +
"</div>" +
"</div>" +
"<div class='col-md-7'>" +
"<div class='form-group'>" +
"<input type='text' class='form-control' name='item_name[]' placeholder='Item name' data-error='Item name cannot empty' required>" +
"<div class='help-block with-errors'></div>" +
"</div>" +
"</div>" +
"<div class='col-md-2' id='btn_action'>" +
"<button id='btn-remove-item' type='button' class='btn btn-danger' style='margin-right: 5px' onclick='removeItem(" + index + ")'><i class='fa fa-minus'></i></button>" +
"<button id='btn-add-item' type='button' class='btn btn-primary' onclick='addItems(" + (index + 1) + ")'><i class='fa fa-plus'></i></button>" +
"</div>" +
"</div>" +
"</div>"
);
index++;
}
function removeItem(index) {
$('#item_' + index).closest("items").find("#btn_action").append(
"<button id='btn-add-item' type='button' class='btn btn-primary' onclick='addItems(" + (index + 1) + ")'><i class='fa fa-plus'></i></button>"
);
$('#item_' + index).remove();
index--;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="row bg-title">
<div class="col-lg-3 col-md-4 col-sm-4 col-xs-12">
<h4 class="page-title">Tambah Transaksi</h4>
</div>
<div class="col-lg-9 col-sm-8 col-md-8 col-xs-12">
<ol class="breadcrumb">
<li>Transaksi</li>
<li class="active">Tambah Transaksi</li>
</ol>
</div>
</div>
<div class="row">
<div class="col-md-6 col-xs-12">
<div class="white-box">
<form action="#" class="form">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label class="control-label">Nomor Transaksi</label>
<input type="text" class="form-control" name="transaction_number" id="transaction_number" disabled>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label class="control-label">Nama Pembeli</label>
<input type="text" class="form-control" name="buyer_name" id="buyer_name">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label class="control-label">Alamat Pembeli</label>
<textarea type="text" class="form-control" name="buyer_address" id="buyer_address" cols="10" rows="5"></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Items</label>
</div>
</div>
</div>
<div id="item_list"></div>
</form>
</div>
</div>
<div class="col-md-6 col-xs-12">
<div class="white-box">
</div>
</div>
</div>
Thanks for your help guys.
What you are looking for is .prev and not .closest.
As correctly pointed out by #Priyal Pithadiya, you will need to add a check before you add element.
var $item = $('#item_' + index)
var shouldAppendButton = !!$item.find('#btn-add-item').length;
if (shouldAppendButton)
$item
.prev()
.find("#btn_action")
.append(
"<button id='btn-add-item' type='button' class='btn btn-primary' onclick='addItems(" + (index + 1) + ")'><i class='fa fa-plus'></i></button>"
);
$item.remove();
Explanation
.closest: It looks in the hierarchy and get to the necessary element. It does not look for previous sibling.
.prev: It looks for previous sibling.
Sample:
var index = 1;
$(document).ready(function() {
addItems(index);
});
function addItems(index) {
$('#btn-add-item').remove();
$('#item_list').append(
"<div class='items' id='item_" + index + "'>" +
"<div class='row'>" +
"<div class='col-md-3'>" +
"<div class='form-group'>" +
"<input type='text' class='form-control' name='item_qty[]' placeholder='Item qty' data-error='Item qty cannot empty' required>" +
"<div class='help-block with-errors'></div>" +
"</div>" +
"</div>" +
"<div class='col-md-7'>" +
"<div class='form-group'>" +
"<input type='text' class='form-control' name='item_name[]' placeholder='Item name' data-error='Item name cannot empty' required>" +
"<div class='help-block with-errors'></div>" +
"</div>" +
"</div>" +
"<div class='col-md-2' id='btn_action'>" +
"<button id='btn-remove-item' type='button' class='btn btn-danger' style='margin-right: 5px' onclick='removeItem(" + index + ")'><i class='fa fa-minus'></i></button>" +
"<button id='btn-add-item' type='button' class='btn btn-primary' onclick='addItems(" + (index + 1) + ")'><i class='fa fa-plus'></i></button>" +
"</div>" +
"</div>" +
"</div>"
);
index++;
}
function removeItem(index) {
var $item = $('#item_' + index)
var shouldAppendButton = !!$item.find('#btn-add-item').length;
if(shouldAppendButton)
$item
.prev()
.find("#btn_action")
.append(
"<button id='btn-add-item' type='button' class='btn btn-primary' onclick='addItems(" + (index + 1) + ")'><i class='fa fa-plus'></i></button>"
);
$item.remove();
index--;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="row bg-title">
<div class="col-lg-3 col-md-4 col-sm-4 col-xs-12">
<h4 class="page-title">Tambah Transaksi</h4>
</div>
<div class="col-lg-9 col-sm-8 col-md-8 col-xs-12">
<ol class="breadcrumb">
<li>Transaksi</li>
<li class="active">Tambah Transaksi</li>
</ol>
</div>
</div>
<div class="row">
<div class="col-md-6 col-xs-12">
<div class="white-box">
<form action="#" class="form">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label class="control-label">Nomor Transaksi</label>
<input type="text" class="form-control" name="transaction_number" id="transaction_number" disabled>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label class="control-label">Nama Pembeli</label>
<input type="text" class="form-control" name="buyer_name" id="buyer_name">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label class="control-label">Alamat Pembeli</label>
<textarea type="text" class="form-control" name="buyer_address" id="buyer_address" cols="10" rows="5"></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Items</label>
</div>
</div>
</div>
<div id="item_list"></div>
</form>
</div>
</div>
<div class="col-md-6 col-xs-12">
<div class="white-box">
</div>
</div>
</div>
Pointers:
IDs must be unique. Having same id in all items div is wrong.
You can also add a delegate instead of adding handlers in every item's markup
I have a list that has several option. I dynamically set an event that whenever a button is clicked, create a table and text input and put the value of list in in there, but I have option that have number value but it didn't set to the value of that input. See my code.
My jquery code:
$("#table_drugs").append("<tr><td>"
+ $("#drugs_list").val() + "<input type='text' name='past_druges_used' value="+$("#drugs_list").val()+">"
+ "</td><td>" + $("#drugs-explain").val()+"<input type='text' name='how_to_use' value="+$("#drugs-explain").val()+">"
+ "</td><td>" + "<button type='button' class='col-sm-7 btn btn-danger pull-right'>delete</button> "
+ "</td></tr>");
And my html:
<div class="col-md-12">
<div id="drugs_list_div" class="form-group">
<div class="col-md-4 col-md-offset-6">
<select id="drugs_list" class="form-control" style="font-family: font-style-3;">
<option>empty</option>
<option>Drugs 1</option>
<option>Drugs 3</option>
<option>Drugs 2</option>
</select>
</div>
</div>
<div id="drugs-explain-div" class="form-group">
<div class="col-md-4 col-md-offset-6">
<input type="text" class="form-control" id="drugs-explain" style="font-family: font-style-1;">
</div>
</div>
</div>
<div class="col-md-12">
<div id="table-drugs-div" class="col-xs-11 list-hide">
<table class="table table-striped" id="table_drugs">
</table>
</div>
</div>
You need to put quotes around your values:
$("#table_drugs").append("<tr><td>"
+ $("#drugs_list").val() + "<input type='text' name='past_druges_used' value='"+$("#drugs_list").val()+"'>"
+ "</td><td>" + $("#drugs-explain").val()+"<input type='text' name='how_to_use' value='"+$("#drugs-explain").val()+"'>"
+ "</td><td>" + "<button type='button' class='col-sm-7 btn btn-danger pull-right'>delete</button> "
+ "</td></tr>");