I'm a new mvc developper, I make a list in my controller, my view show this list and for each row i have a button for a modal view.I want to pass the data of the ViewBag in my list according for each row in my modal.
This is my modal html:
<div class="modal" id="addBadgetoStudentModal-#item.ID" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg animated bounceInDown">
<div class="modal-content">
#using (Html.BeginForm("AddBadgeToStudent", "Badges", new { ID = item.ID }, FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="modal-header">
<h4 class="modal-title">Badges</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<div class="">
<div class="row">
#if (ViewBag.Badges != null)
{
for (var i = 0; i < ViewBag.Badges.Count; i++)
{
<div class="col-lg-3 col-sm-6 col-md-4">
<div class="team-member ">
<div class="row margin-0">
<div class="team-info" style="text-align:center; border: 1.2pt solid #1874BF;">
<img src="#ViewBag.Badges[i].ImageURL" style="width:80%;" class="img-fluid" />
</div>
<div class="team-info" style="text-align:center; width:100%;">
#ViewBag.Badges[i].Label
<br />
<input id="Badge_#ViewBag.Badges[i].ID" class="checkBoxBadgeClass" type="checkbox" />
</div>
</div>
</div>
</div>
}
}
</div>
</div>
</div>
</div>
<div class="modal-footer">
<i class="fa fa-plus-circle"></i> #Resource.Add
</div>
}
</div>
</div>
</div>
<a class="fa fa-pencil-alt" data-toggle="modal" href="#addBadgetoStudentModal-#item.ID" onclick="btnModal()"></a>
This is my List Html View:
#foreach (var item in Model)
{
<tr id="#item.ID">
<td style="text-align:center; width:5%;">
#Html.DisplayFor(modelItem => item.ID)
</td>
<td style="text-align: center; width:25%;">
#item.FullName
</td>
<td style="width:450px;">
#for (var i = 0; i < item.BadgesAssigned.Count; i++)
{
<img src="#item.BadgesAssigned[i].ImageUrl" width="50" title="#item.BadgesAssigned[i].Name" style="float:left;" />
}
<input type="hidden" id="studentBadges_#item.ID" value="#String.Join(",", item.BadgesAssigned.Select(x => x.ID.ToString()))"/>
</td>
}
and this my controller to get my student list and in another table get the badge assigned to a student, so in the list view the student can have 20 badges/25:
public ActionResult BadgeManagement(int? CohortId, int? id)
{
ViewBag.CohortId = db.Cohorts.Select(p => new SelectListItem
{
Text = p.Name,
Value = p.ID.ToString()
});
if (CohortId != null ? CohortId > 0 : false)
{
var cs = db.CohortSubscriptions.Where(student => student.CohortId == CohortId).Include(c => c.Cohorts).Include(c => c.Registrations);
List<BadgesByStudentViewModel> badgesByStudentList = new List<BadgesByStudentViewModel>();
foreach (var student in cs) {
badgesByStudentList.Add(new BadgesByStudentViewModel
{
ID = student.ID,
FullName = student.Registrations.FullName,
BadgesAssigned = db.Enrolled_Students_Badges.Where(x => x.CohortSubscriptionId == student.ID).Select(x => new BadgesAssigned
{
ID = x.ID,
Name = x.Label,
ImageUrl = x.ImageURL
}).ToList()
});
}
ViewBag.Badges = db.Badges.ToList();
return View(badgesByStudentList.ToList());
}
return View(new List<BadgesByStudentViewModel>());
}
I found my solution
This is my html:
<tbody>
#foreach (var item in Model)
{
<tr id="#item.ID">
<td style="text-align:center; width:5%;">
#Html.DisplayFor(modelItem => item.ID)
</td>
<td style="text-align: center; width:25%;">
#item.FullName
</td>
<td style="width:450px;">
#for (var i = 0; i < item.BadgesAssigned.Count; i++)
{
<img src="#item.BadgesAssigned[i].ImageUrl" width="50" title="#item.BadgesAssigned[i].Name" style="float:left;" />
}
</td>
<td style="text-align:center; width:5%;">
<button style="border:none;background: transparent;" data-studentid="#item.ID" data-studentname="#item.FullName" data-badges="#String.Join(",", item.BadgesAssigned.Select(x => x.ID.ToString()))" data-toggle="modal" data-target="#addBadgetoStudentModal" class="modalLink"><i class="fa fa-pencil-alt"></i></button>
</td>
</tr>
}
</tbody>
</table>
<div class="modal" id="addBadgetoStudentModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg animated bounceInDown">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Badges</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<div class="">
<u>#Resource.AddBadgeToStudent:</u>
<br />
<br />
<div class="row">
#if (ViewBag.Badges != null)
{
for (var i = 0; i < ViewBag.Badges.Count; i++)
{
<div class="col-lg-3 col-sm-6 col-md-4">
<div class="team-member ">
<div class="row margin-0">
<div class="team-info" style="text-align:center; border: 1.2pt solid #1874BF;">
<img src="#ViewBag.Badges[i].ImageURL" style="width:80%;" class="img-fluid" />
</div>
<div class="team-info" style="text-align:center; width:100%;">
#ViewBag.Badges[i].Label
<br />
<input id="Badge_#ViewBag.Badges[i].ID" data-badgeid="#ViewBag.Badges[i].ID" data-label="#ViewBag.Badges[i].Label" class="checkBoxBadgeClass" type="checkbox" />
</div>
</div>
</div>
</div>
}
}
</div>
</div>
</div>
</div>
<div class="modal-footer">
<i class="fa fa-plus-circle"></i> #Resource.Edit
</div>
</div>
</div>
</div>
and this is my jquery:
currentStudentId = null;
currentAssignedBadge = [];
$('#BadgeAssignmentTable').dataTable({
responsive: true,
aLengthMenu: [
[10, 25, 50, 100, -1],
[10, 25, 50, 100, "All"]
]
});
$(".modalLink").on("click", function () {
var $pencil = $(this);
var studentId = $pencil.data('studentid');
var badges = $pencil.data('badges');
var studentName = $pencil.data("studentname");
PrepareBadgesModal(studentId, badges.split(","), studentName);
});
PrepareBadgesModal = function (studentId, assignedBadges, studentName) {
currentStudentId = studentId;
console.log(assignedBadges);
currentAssignedBadge = [];
$.each(assignedBadges, function (k, v) { return currentAssignedBadge.push(parseInt(v, 10)); });
$.each(assignedBadges, function (k, v) {
var $badge = $("#Badge_" + v);
$badge.prop("checked", true);
var label = $badge.data("label");
$badge.on("click", function (event) {
var res = ConfirmRemoveBadge($(this), label, studentName);
event.stopPropagation();
});
});
}
ConfirmRemoveBadge = function ($badge, label, studentName) {
var txt = "ATTENTION\r\rÊtes-vous certain de vouloir retirer le badge \"" + label + "\" à " + studentName + "?";
var r = confirm(txt);
if (r == true) {
$badge.prop("checked", false);
$badge.unbind("click");
} else {
$badge.prop("checked", true);
}
}
$("#AssignBadges").click(function () {
ModifyBadgesAction();
});
ModifyBadgesAction = function (badgeList) {
var selBadgeLst = $('input[id^=Badge_]:checked').map(function (k, v) { return parseInt($(v).data('badgeid'), 10); });
//TODO: Close the modal
var removedLst = $.grep(currentAssignedBadge, function (v, k) {
return $.grep(selBadgeLst, function (vv, kk) {
return v == vv;
}).length == 0;
});
var AddedList = $.grep(selBadgeLst, function (v, k) {
return $.grep(currentAssignedBadge, function (vv, kk) {
return v == vv;
}).length == 0;
});
var jsonData = JSON.stringify({ studentId : currentStudentId, AddedList: AddedList, removedLst: removedLst });
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: '/Badges/ModifyBadgesAction',
data: jsonData,
success: function (data, textStatus, jqXHR) {
//console.log(data, textStatus, jqXHR);
if (data.code == 0) {
ApplyBadgeActionSuccess(data);
}
else {
ApplyBadgeActionError(data);
}
},
error: function (jqXHR, textStatus, errorThrown) {
ApplyBadgeActionError({ code: jqXHR.status, message: "Technical Error", data: [{ jqXHR: jqXHR, error: errorThrown }] });
}
});
};
ApplyBadgeActionSuccess = function (data) {
alert(data.message);
window.location.reload(true);
}
ApplyBadgeActionError = function (data) {
alert(data.message);
}
Related
I have a view that has a button for applying for a job, and this button is redirected to a HttpPost action method that handles the apply logic and then returns a JSON result to the same view. as shown below:
// POST: Application/Apply
[HttpPost]
public ActionResult Apply(string idUser, int idAnnouncement)
{
try
{
// TODO: Add insert logic here
// Search for the candidate that has the same Hash code as idUser param
Candidate appliedCandidate = db.Candidates.Where(c => c.CandidateSecondID.Equals(idUser)).FirstOrDefault();
// todo: check if Candidate is already applyed to job
var check = db.Applications.Where(a => a.CandidateID.Equals(appliedCandidate.CandidateID) && a.AnnouncementID.Equals(idAnnouncement)).FirstOrDefault();
if (check == null)
{
Application newApp = new Application
{
AnnouncementID = idAnnouncement,
CandidateID = appliedCandidate.CandidateID,
ApplicationDate = DateTime.Now,
};
db.Applications.Add(newApp);
db.SaveChanges();
return this.Json(new
{
EnableSuccess = true,
SuccessTitle = "Success",
SuccessMsg = "Your application has been sent successfully!"
});
}
else
{
return this.Json(new
{
EnableSuccess = false,
ErrorTitle = "Warning",
ErrorMsg = "You are already applayed for this Job!"
});
}
}
catch
{
return View();
}
}
Here is the AJAX call:
$.ajax({
method: "POST",
url: action,
success: function (result) {
if (result.EnableSuccess) {
swal(
result.SuccessTitle,
result.SuccessMsg,
'success'
)
} else {
swal(
result.ErrorTitle,
result.ErrorMsg,
'warning'
)
}
},
error: function (err) {
console.log(err);
}
})
and here is the full view :
#model IEnumerable<JobPostingProject.Models.Announcement>
#using Microsoft.AspNet.Identity;
#using Microsoft.AspNet.Identity.Owin;
#{
ViewBag.Title = "List of jobs";
}
#using (Html.BeginForm("Index", "Announcement", FormMethod.Get))
{
<div class="row mb-3">
<div class="col-lg-3 ">
<div class="title">
<i class="fas fa-search mr-2"></i>
<input type="text" name="titleInput" class="title__input form-control border-0" placeholder="Job Title" value="#ViewBag.Job" />
</div>
</div>
<div class="col-lg-3">
<div class="city">
<i class="fas fa-map-marker-alt mr-2"></i>
<input type="text" name="cityInput" class="city__input form-control border-0" placeholder="Location" value="#ViewBag.City" />
</div>
</div>
<div class="col-lg-3">
<div class="categorie">
#Html.DropDownList("Categories", null, "Job Category", new { #class = "form-control" })
</div>
</div>
</div>
<div class="row my-4">
<div class="col-lg-3">
<div class="date mb-4">
#*<i class="fas fa-search mr-2"></i>*#
<input type="date" name="dateInf" class="title__input form-control" style="border: 1px solid #ced4da; padding-left: 10px;" />
</div>
</div>
<div class="col-lg-3">
<div class="date mb-4">
#*<i class="fas fa-search mr-2"></i>*#
<input type="date" name="dateSup" class="title__input form-control" style=" border: 1px solid #ced4da;
padding-left: 10px;
" />
</div>
</div>
<div class="col-lg-3">
<div class="level">
#Html.DropDownList("Levels", ViewBag.Levels as SelectList, "Level", new { #class = "form-control" })
</div>
</div>
</div>
<div class="search">
<input type="submit" value="Search" class="text-white text-decoration-none btn btn-primary search__button" />
#*#Html.ActionLink("Search", "Index", "Announcement", null, new { #class = "text-white text-decoration-none btn btn-primary search__button" })*#
</div>
}
<!--list of all jobs searched for-->
<div class="container mt-5">
#{
if (!Model.Any())
{
<p class="text-center p-3 text-secondary">No job found with the chosen critiria</p>
}
else
{
<p class="text-secondary">#ViewBag.TotalResults job results found</p>
foreach (var item in Model)
{
<div class="row">
<div class="col-lg-7">
<div class="jobs">
#using (Html.BeginForm("Apply", "Application", new { idUser = User.Identity.GetUserId(), idAnnouncement = item.AnnouncementID }, FormMethod.Post, new { #class = "w-100 AnnonceForm" }))
{
<div class="job">
<div class="job__header d-flex align-items-center justify-content-between flex-wrap mb-0">
<h5 class="job__title">#item.Title</h5>
<h2 class="job__city">#item.Location</h2>
</div>
<h5 class="job__datetime">Posted in #item.PublicationDate.ToString("dd/mm/yyyy")</h5>
<h5 class="job__company-name mb-4">By #item.Company.Name</h5>
<div class="job__actions d-flex align-items-center">
<p class="job__apply my-0 mr-2">
#Html.ActionLink("More details", "AnnouncementDetails", "Application", new { idAnnouncement = item.AnnouncementID }, new { #class = "btn btn-primary" })
</p>
#if (!User.IsInRole("Company"))
{
<input type="submit" value="Apply Now" class="btn btn-outline-primary submit-btn">
}
</div>
</div>
}
</div>
</div>
<div class="col-lg-5"></div>
</div>
}
}
}
</div>
#section AnnouncementIndex {
<link href="#Url.Content("~/Content/Home.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/Announcement/AnnouncementIndex.css")" rel="stylesheet" type="text/css" />
}
#section Scripts{
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script>
let submitButtons = document.querySelectorAll(".submit-btn");
for (let i = 0; i < submitForms.length; i++) {
submitButtons[i].addEventListener("submit", e => {
e.preventDefault();
var el = this.parentElement;
while (el.className != 'AnnonceForm') {
el = el.parentElement;
}
//el is now your parent
let action = el.attr("action");
$.ajax({
method: "POST",
url: action,
data: {},
dataType: "json",
success: function (result) {
console.log("entered success block");
if (result.EnableSuccess) {
swal(
result.SuccessTitle,
result.SuccessMsg,
'success'
)
} else {
swal(
result.ErrorTitle,
result.ErrorMsg,
'warning'
)
}
},
error: function (err) {
console.log(err);
}
})
return false;
})
}
</script>
}
BUT, for some reason, I get this plain JSON result instead of actually returning to the success function in the AJAX call.
For some reason data validation doesn't work. Although, if I add an alert statement after valid() method inside .click(), it will alert, which means that data is considered valid anyways. I tried different approaches including making actionbutton outside form in html file, but that didn't solve the problem. What else could that be?
Currently there are no exceptions or errors.
JavaScript:
$(function () {
$("#EmployeeForm").validate({
rules: {
TextBoxTitle: { maxlength: 4, required: true, validTitle: true },
TextBoxFirstname: { maxlength: 25, required: true },
TextBoxLastname: { maxlength: 25, required: true },
TextBoxEmail: { maxlength: 40, required: true, email: true },
TextBoxPhone: { maxlength: 15, required: true }
},
errorElement: "div",
messages: {
TextBoxTitle: {
required: "required 1-4 chars.", maxlength: "required 1-4 chars.",
validTitle: "Mr. Ms. Mrs. or Dr."
},
TextBoxFirstname: {
required: "required 1-25 chars.", maxlength: "required 1-25 chars."
},
TextBoxLastname: {
required: "required 1-25 chars.", maxlength: "required 1-25 chars."
},
TextBoxPhone: {
required: "required 1-15 chars.", maxlength: "required 1-15 chars."
},
TextBoxEmail: {
required: "required 1-40 chars.", maxlength: "required 1-40 chars.",
email: "need vaild email format"
}
}
});
//custom validator
$.validator.addMethod("validTitle", function (value, element) { // custom rule
return this.optional(element) || (value == "Mr." || value == "Ms." || value == "Mrs." || value == "Dr.");
}, "");
//click event handler for the employee list
$("#employeeList").click(function (e) {
if (!e) e = window.event;
var Id = e.target.parentNode.id;
if (Id === 'employeeList' || Id === '')
Id = e.target.id;
var data = JSON.parse(localStorage.getItem('allemployees'));
clearModalFields();
//add, update or delete?
if (Id === '0') {
setupForAdd();
$('#ImageHolder').html('');
} else {
setupForUpdate(Id, data);
}
});
getAll('');
$("#srch").keyup(function () {
filterData();
});
function filterData() {
filteredData = [];
allData = JSON.parse(localStorage.getItem('allemployees'));
$.each(allData, function (n, i) {
if (~i.LastName.indexOf($("#srch").val())) {
filteredData.push(i);
}
});
buildEmployeeList(filteredData, false);
}
function loadDepartmentDDL(empdiv) {
html = '';
$('#ddlDivs').empty();
var alldepartments = JSON.parse(localStorage.getItem('alldepartments'));
$.each(alldepartments, function () {
html += '<option value="' + this['Id'] + '">' + this['DepartmentName'] + '</option>';
});
$('#ddlDivs').append(html);
$('#ddlDivs').val(empdiv);
}
$("#actionbutton").click(function () {
if ($("#EmployeeForm").valid()) {
if ($('#actionbutton').val() === 'Update') {
update();
} else {
add();
}
}
else {
$("#lblstatus").text("fix existing problems");
$("#lblstatus").css({ "color": "red" });
}
return false;
});
$('#deletebutton').click(function () {
var deleteEmployee = confirm('Really delete this employee?');
if (deleteEmployee) {
_delete();
return !deleteEmployee;
}
else {
return deleteEmployee;
}
});
function setupForUpdate(Id, data) {
$('#actionbutton').val('Update');
$('#modaltitle').html('<h4>Employee Update</h4>');
$('#deletebutton').show();
$.each(data, function (index, employee) {
if (employee.Id === parseInt(Id)) {
$('#TextBoxEmail').val(employee.Email);
$('#TextBoxTitle').val(employee.Title);
$('#TextBoxFirstname').val(employee.FirstName);
$('#TextBoxLastname').val(employee.LastName);
$('#TextBoxPhone').val(employee.Phoneno);
$('#ImageHolder').html('<img height="120" width="110" src="data:image/png;base64,' + localStorage.getItem('StaffPicture') + '"/>');
localStorage.setItem('Id', employee.Id);
localStorage.setItem('DepartmentId', employee.DepartmentId);
localStorage.setItem('Timer', employee.Timer);
loadDepartmentDDL(employee.DepartmentId);
return false;
} else {
$('#status').text('no employee found');
}
});
$('#theModal').modal('toggle');
}
function setupForAdd() {
clearModalFields();
$('#actionbutton').val('Add');
$('#modaltitle').html('<h4>Add New Employee</h4>');
$('#deletebutton').hide();
$('#theModal').modal('toggle');
}
//build the list
function buildEmployeeList(data, allemployees) {
$('#employeeList').empty();
div = $('<div class="list-group"><div>' +
'<span class="col-xs-4 h3">Title</span>' +
'<span class="col-xs-4 h3">First</span>' +
'<span class="col-xs-4 h3">Last</span>' +
'</div>');
div.appendTo($('#employeeList'))
if (allemployees) {
localStorage.setItem('allemployees', JSON.stringify(data));
}
btn = $('<button class="list-group-item" id="0">...Click to add employee</button>');
btn.appendTo(div);
$.each(data, function (index, emp) {
btn = $('<button class="list-group-item" id="' + emp.Id + '">');
btn.html(
'<span class="col-xs-4" id="employeetitle' + emp.Id + '">' + emp.Title + '</span>' +
'<span class="col-xs-4" id="employeefname' + emp.Id + '">' + emp.FirstName + '</span>' +
'<span class="col-xs-4" id="employeelastname' + emp.Id + '">' + emp.LastName + '</span>');
btn.appendTo(div);
});
}
//get all employees
function getAll(msg) {
$('#status').text('Finding employee information...');
ajaxCall('Get', 'api/employees', '')
.done(function (data) {
buildEmployeeList(data, true);
if (msg === '')
$('#status').text('Employees Loaded');
else
$('#status').text(msg + ' - Employees Loaded');
})
.fail(function (jqXHR, textStatus, errorThrown) {
errorRoutine(jqXHR);
});
ajaxCall('Get', 'api/departments/', '')
.done(function (data) {
localStorage.setItem('alldepartments', JSON.stringify(data));
})
.fail(function (jqXHR, textStatus, errorThrown) {
alert('error');
});
}
function clearModalFields() {
$('#TextBoxFirstname').val('');
$('#TextBoxLastname').val('');
$('#TextBoxEmail').val('');
$('#TextBoxTitle').val('');
$('#TextBoxPhone').val('');
$('#modalStatus').text('');
localStorage.removeItem('Id');
localStorage.removeItem('DepartmentId');
localStorage.removeItem('Timer');
loadDepartmentDDL(-1);
}
function add() {
emp = new Object();
emp.Title = $("#TextBoxTitle").val();
emp.FirstName = $("#TextBoxFirstname").val();
emp.Lastname = $("#TextBoxLastname").val();
emp.Phoneno = $("#TextBoxPhone").val();
emp.Email = $("#TextBoxEmail").val();
emp.DepartmentId = $("#ddlDivs").val();
ajaxCall('post', 'api/employees/', emp)
.done(function (data) {
getAll(data);
})
.fail(function (jqXHR, textStatus, errorThrown) {
errorRoutine(jqXHR);
});
$('#theModal').modal('toggle');
return false;
}
function update() {
emp = new Object();
emp.Title = $("#TextBoxTitle").val();
emp.FirstName = $("#TextBoxFirstname").val();
emp.Lastname = $("#TextBoxLastname").val();
emp.Phoneno = $("#TextBoxPhone").val();
emp.Email = $("#TextBoxEmail").val();
emp.Id = localStorage.getItem('Id');
emp.DepartmentId = localStorage.getItem('DepartmentId');
emp.DepartmentName = $('#ddlDivs').val();
emp.Timer = localStorage.getItem('Timer');
if (localStorage.getItem('StaffPicture')) {
emp.Picture64 = localStorage.getItem('StaffPicture');
}
ajaxCall('put', 'api/employees/', emp)
.done(function (data) {
$("#status").text(data);
if (data.indexOf('not') == -1) {
$('#ImageHolder').html('<img height="120" width="110" src="data:image/png;base64,' + localStorage.getItem('StaffPicture') + '"/>')
}
})
.fail(function (jqXHR, textStatus, errorThrown) {
errorRoutine(jqXHR);
});
$('#theModal').modal('toggle');
return false;
}
$("input:file").change(() => {
var reader = new FileReader();
var file = $('#fileUpload')[0].files[0];
if (file) {
reader.readAsBinaryString(file);
}
reader.onload = function (readerEvt) {
//get binary data then convert to encoded string
var binaryString = reader.result;
var encodedString = btoa(binaryString);
localStorage.setItem('StaffPicture', encodedString);
}
});
//delete employee
function _delete() {
ajaxCall('Delete', 'api/employees/' + localStorage.getItem('Id'), '')
.done(function (data) {
getAll(data);
})
.fail(function (jqXHR, textStatus, errorThrown) {
errorRoutine(jqXHR);
});
$('#theModal').modal('toggle');
}
//cal ASP.NET WEB API server
function ajaxCall(type, url, data) {
return $.ajax({
type: type,
url: url,
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
processData: true
});
}
function errorRoutine(jqXHR) {
if (jqXHR.responseJSON == null) {
$('#status').text(jqXHR.responseText);
}
else {
$('#status').text(jqXHR.responseJSON.Message);
}
if (jqXHR.responseJSON === null) {
$("#lblstatus").text(jqXHR.responseText);
}
else {
$("#lblstatus").text(jqXHR.responseJSON.Message);
}
} //errrorRoutine
});
HTML:
<!DOCTYPE html>
<html>
<head>
<title>CRUD</title>
<meta charset="utf-8" />
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<link href="Content/employee.css" rel="stylesheet" />
<link rel="icon" href="data:;base64,iVBORw0KGgo=" />
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top" style="background-color: #686868">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">#2</a>
<div class="col-xs-2"> </div>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav" id="menu">
<li>Home</li>
<li>CRUD</li>
</ul>
<div class="input-group col-xs-push-3 col-sm-2 col-xs-4 navbar navbar-brand" style="position:absolute; left:1200px;">
<span class="input-group-addon">
<span class="glyphicon glyphicon-search"></span>
</span>
<input type="text" id="srch" class="form-control form-md">
</div>
<div id="version" style="color:white; float:right;"><p>v2.0</p></div>
</div>
</nav>
<div class="container">
<div style="padding-top:15%;">
<div class="panel panel-default">
<div class="panel-heading text-center" id="status" style="font-weight:bold;"></div>
<div class="panel-body">
<div id="employeeList"></div>
</div>
</div>
</div>
</div>
<form id="EmployeeForm" name="EmployeeModalForm" method="post" action="">
<div class="modal fade" id="theModal" data-backdrop="static">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">X</button>
<div id="modelTitle"></div>
<h4>Employee Update - v2.0</h4>
</div>
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-heading text-center">
Employee Information
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-4">Title:</div>
<div class="col-xs-8"><input type="text" placeholder="enter title" id="TextBoxTitle" class="form-control" /></div>
</div>
<div class="row">
<div class="col-xs-4">First:</div>
<div class="col-xs-8"><input type="text" placeholder="enter first name" id="TextBoxFirstname" class="form-control" value="Joe" /></div>
</div>
<div class="row">
<div class="col-xs-4">Surname:</div>
<div class="col-xs-8"><input type="text" placeholder="enter last name" id="TextBoxLastname" class="form-control" value="Blow" /></div>
</div>
<div class="row">
<div class="col-xs-4">Phone#:</div>
<div class="col-xs-8"><input type="text" placeholder="enter phone" id="TextBoxPhone" class="form-control" value="(555)555-5555" /></div>
</div>
<div class="row">
<div class="col-xs-4">Email:</div>
<div class="col-xs-8"><input type="text" placeholder="enter email" id="TextBoxEmail" class="form-control" value="jb#ss.com" /></div>
</div>
<div class="row">
<div class="col-xs-4"><strong>Department:</strong></div>
<div class="col-xs-8">
<select id="ddlDivs" name="ddlDivs" class="form-control"></select>
</div>
</div>
<div class="row">
<div class="col-xs-4">Picture:</div>
<div class="col-xs-8" id="ImageHolder" style="padding-top:2%;" />
</div>
</div>
<div class="panel-footer"> </div>
</div>
</div>
<div class="modal-footer">
<div class="col-xs-8"><input id="fileUpload" type="file" /></div>
<div class="col-xs-4"><input type="submit" value="Update" id="actionbutton" class="btn btn-default" style="position:absolute; right:100px; z-index:100; top:30px" /></div>
<div class="col-xs-4"><input type="button" value="Delete" id="deletebutton" class="btn btn-danger" style="position:absolute; top:30px; right:5px;" /></div>
<label class="col-xs-12 text-center row" id="lblstatus" style="padding-top:10px;"></label>
<div id="status" class="text-left" style="padding-top:5%;"></div>
</div>
</div>
</div>
</div>
</form>
<script src="Scripts/jquery-3.2.1.min.js"></script>
<script src="Scripts/jquery.validate.min.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
<script src="Scripts/employeecrud.js?newversion"></script> <!--Google Chrome does not load the newest version of the code. Adding unique string helps-->
</body>
</html>
jQuery validator works off of the name of the element not its id.
So for lets say for example on your email input you should add: name="TextBoxEmail"
Like this:
<input type="text" placeholder="enter email" id="TextBoxEmail" name="TextBoxEmail"
class="form-control" value="jb#ss.com" />
Good Day!
I'm working on my project right now and I need to dynamically add form when button click. I have a nested accordion and inside the accordion is ng-select. To make it clear this is my code
<div class="box box-default" *ngFor="let form of forms; let form_array_index = index">
<div class="box-header with-border text-center">
<h3 class="box-title">
<div class="row">
<div class="col-md-4">
<select2 id="segment" name="segment"
[data]="add_segment"
[width]="293"
[value]="segment_value"
(valueChanged)="changedSegment($event, form_array_index)"
required>
</select2>
</div>
</div>
</h3>
<div class="box-tools pull-right">
</div>
</div>
<div class="box-body">
<div class="row">
<div class="col-md-2">
<label for="category">Values:</label>
<select2 id="category" name="category"
[options]="options"
[data]="add_category"
[width]="293"
[value]="category_value"
(valueChanged)="changedCategory($event, form_array_index)"
required>
</select2>
</div>
</div>
<div class="box-header with-border text-center" *ngIf="cat_value">
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion1" href="#{{ category_current[form_array_index] }}">{{collection_category[form_array_index].category}}
</a>
</h5>
</div>
<div id="{{ category_current[form_array_index] }}" class="panel-collapse collapse">
<div class="panel-body">
<div class="panel-body">
<button class="btn btn-success btn-xs pull-left" (click)="addQuestions()">Add Question</button>
<div class="row" >
<select2 *ngIf="query" id="question" name="question"
[data]="add_question"
[width]="293"
[value]="question_value"
(valueChanged)="changedQuestion($event)"
required>
</select2>
</div>
<button class="btn btn-success btn-xs pull-left" (click)="addSubCat()">Add Sub Category</button>
<div class="row" >
<select2 *ngIf="subcat" id="subcategory" name="subcategory"
[options]="options"
[data]="add_subcategory"
[width]="293"
[value]="subcategory_value"
(valueChanged)="changedSubcategory($event, form_array_index)"
required>
</select2>
</div>
<div class="panel-group" id="accordion21" *ngIf="subcat">
<ul class="list-group">
<li class="list-group-item" >
<div class="panel">
<a data-toggle="collapse" data-parent="#accordion21" href="#{{ subcategory_current }}" >
<strong>{{ get_subcategory }} </strong>
</a>
<div id="{{subcategory_current}}" class="panel-collapse collapse">
<div class="panel-body">
<label for="question">Question:</label>
<select2 id="question" name="question"
[data]="add_question"
[width]="293"
[value]="question_value"
(valueChanged)="changedQuestion($event)"
required>
</select2> <br>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div></div>
</div>
<div class="box-tools pull-right">
</div>
</div>
</div>
This means in SEGMENT it can have multiple CATEGORY and inside category it can have a question or they they Choose SUB CATEGORY and they have to choose a question
This is my component.ts
public collection_category = [];
public collection_subcategory = [];
addSegment(){
this._q_service.addSegment().
subscribe(
data => {
this.add_segment = Array.from(data);
let id = 0;
let text = 'Select Segment';
this.add_segment.unshift({id,text});
// this.segment_value = [];
this.segment_current = this.segment_value;
},
err => console.error(err)
);
}
changedSegment(data: any, form_array_index: any) {
this.segment_current = data.value;
if(this.segment_current.length > 0){
for (let i = 0; i < this.add_segment.length; ++i) {
if (this.add_segment[i].id == this.category_current) {
this.collection_category[form_array_index].segment = this.add_segment[i].text;
}
}
}
console.log('segment', this.collection_category);
}
addCategory(){
this._q_service.addCategory().
subscribe(
data => {
this.add_category = Array.from(data);
this.category_value = [];
this.options = {
multiple: true
}
let id = 0;
let text = 'Select Category';
this.add_category.unshift({id,text});
this.category_value = [];
// this.category_current.push(this.category_value);
// console.log(this.category_current);
},
err => console.error(err)
);
}
changedCategory(data: any, form_array_index: any ) {
this.category_current = data.value;
if(this.category_current.length > 0){
let len = this.add_category.length;
for (let i = 0; i < len; ++i) {
if (this.add_category[i].id == this.category_current) {
this.get_category = this.add_category[i].text;
this.collection_category[form_array_index].category = this.add_category[i].text;
}
}
this.cat_value = true;
}
console.log(this.collection_category);
this.addSubCategory();
this.addQuestion();
}
addSubCategory(){
this._q_service.addSubCategory().
subscribe(
data => {
this.add_subcategory = Array.from(data);
this.subcategory_value = [];
this.options = {
multiple: true
}
let id = 0;
let text = 'Select Sub Category';
this.add_subcategory.unshift({id,text});
this.subcategory_value = [];
this.subcategory_current = this.subcategory_value;
},
err => console.error(err)
);
}
changedSubcategory( data: any, form_array_index: any ) {
this.subcategory_current = data.value;
if(this.subcategory_current.length > 0){
let len = this.add_subcategory.length;
for (let i = 0; i < len; ++i) {
if (this.add_subcategory[i].id == this.subcategory_current) {
this.get_subcategory = this.add_subcategory[i].text;
this.collection_category[form_array_index].subcategory = this.add_subcategory[i].text;
// this.collection_subcategory[form_array_index].subcategory_collection = [];
}
}
this.sub_value = true;
}
}
addQuestion(){
this._q_service.questionList().
subscribe(
data => {
this.add_question = Array.from(data);
this.question_value = [];
let id = 0;
let text = 'Select Question';
this.add_question.unshift({id,text});
this.subcategory_value = ['0'];
this.question_current = this.question_value;
},
err => console.error(err)
);
}
changedQuestion(data: any) {
this.question_current = data.value;
if(this.question_current != 0){
let len = this.add_question.length;
for (let i = 0; i < len; ++i) {
if (this.add_question[i].id == this.question_current) {
this.get_question = this.add_question[i].text;
}
}
}
}
addFormRow(){
let new_form ={
id: '',
segment: '',
category: '',
subcategory: '',
question: ''
};
// this.category_current.push(0);
let segment_categories = {
segment: '',
category: '',
subcategory: '',
question: ''
};
//this.category_current[form_array_index].category
this.collection_category.push(segment_categories);
this.forms.push(new_form);
}
*And every time the user hit the Add Form button it dynamically add form *
But it gives me an error every time I add form the first accordion is not working on the second form but the first form is working well
Im creating two DevExpress ListBox to set a relation between products and clients.
See Moving Items between List Boxes
So:
My Controller C#
public ActionResult ReglaCreate()
{
if (Authentication.User.Identity.IsAuthenticated)
{
Service service= new Service();
var articulos = service.GetArt();
var locales = service.GetLoc();
Session["Articulos"] = articulos;
Session["Locales"] = locales;
return View();
}
else
return RedirectToAction("Login", "Account");
}
DevExpress ListGrid
<div class="wrapper wrapper-content animated fadeInRight" id="ReglaCreateController" ng-controller="ReglaController">
<div class="row">
<div class="ibox-content">
<form class="form-horizontal">
<div class="form-group" style="width:50%">
<label class="col-lg-2 control-label" style="float:left">Nombre</label>
<textarea style="font-size:15px;text-align:left;width:350px;height:40px;margin-left:15px;" class="control-label" id="lblNombreRegla">{{lblNombreRegla}}</textarea>
</div>
</form>
<br />
<div class="form-group">
<div class="col-md-4" style="width:17.5%">
<span style="float:right"><label class="col-lg-2 control-label" style="width:180px">Locales disponibles</label></span>
</div>
<div class="col-md-4" style="padding-left: 495px">
<span style="float:left"><label class="col-lg-2 control-label" style="width:180px">Locales elegídos</label></span>
</div>
</div>
<table style="height">
<tr>
<td>
#Html.DevExpress().ListBox(settings =>
{
settings.Name = "lbAvailableLocales";
settings.Properties.SelectionMode = ListEditSelectionMode.CheckColumn;
var locales = (List<LocalViewModel>)Session["Locales"];
foreach (var local in locales)
{
settings.Properties.Items.Add(local.Nombre, local.ID);
}
settings.Properties.ClientSideEvents.SelectedIndexChanged = "function(s, e) { UpdateButtonStateLocales(); }";
settings.Properties.EnableClientSideAPI = true;
settings.Width = System.Web.UI.WebControls.Unit.Pixel(350);
settings.Height = System.Web.UI.WebControls.Unit.Pixel(200);
}).GetHtml()
</td>
<td style="padding: 60px">
<div class="form-horizontal">
<div class="form-group">
<div class="col-md-4">
#Html.DevExpress().Button(settings =>
{
settings.Name = "btnMoveSelectedItemsToRightLocales";
settings.Text = "Agregar >";
settings.ClientSideEvents.Click = "function(s, e) { AddSelectedItemsLocales(); }";
}).GetHtml()
</div>
<div class="col-md-4">
#Html.DevExpress().Button(settings =>
{
settings.Name = "btnMoveAllItemsToRightLocales";
settings.Text = "Agregar todos >>";
settings.ClientSideEvents.Click = "function(s, e) { AddAllItemsLocales(); }";
}).GetHtml()
</div>
</div>
<div class="form-group">
<div class="col-md-4">
#Html.DevExpress().Button(settings =>
{
settings.Name = "btnMoveSelectedItemsToLeftLocales";
settings.Text = "< Eliminar";
settings.ClientSideEvents.Click = "function(s, e) { RemoveSelectedItemsLocales(); }";
}).GetHtml()
</div>
<div class="col-md-4">
#Html.DevExpress().Button(settings =>
{
settings.Name = "btnMoveAllItemsToLeftLocales";
settings.Text = "<< Eliminar todos";
settings.ClientSideEvents.Click = "function(s, e) { RemoveAllItemsLocales(); }";
}).GetHtml()
</div>
</div>
</div>
</td>
<td>
#Html.DevExpress().ListBox(settings =>
{
settings.Name = "lblChoosenLocales";
settings.Properties.SelectionMode = ListEditSelectionMode.CheckColumn;
settings.Properties.ClientSideEvents.SelectedIndexChanged = "function(s,e) { UpdateButtonStateLocales(); }";
settings.Properties.EnableClientSideAPI = true;
settings.Width = System.Web.UI.WebControls.Unit.Pixel(350);
settings.Height = System.Web.UI.WebControls.Unit.Pixel(200);
}).GetHtml()
</td>
</tr>
</table>
<br />
<div class="form-group">
<div class="col-md-4" style="width:17.5%">
<span style="float:right"><label class="col-lg-2 control-label" style="width:180px">Artículos disponibles</label></span>
</div>
<div class="col-md-4" style="padding-left: 495px">
<span style="float:left"><label class="col-lg-2 control-label" style="width:180px">Artículos elegídos</label></span>
</div>
</div>
<table>
<tr>
<td>
#Html.DevExpress().ListBox(settings =>
{
settings.Name = "lbAvailable";
settings.Properties.SelectionMode = ListEditSelectionMode.CheckColumn;
var articulos = (List<ArticuloViewModel>)Session["Articulos"];
foreach (var articulo in articulos)
{
settings.Properties.Items.Add(articulo.Nombre, articulo.ID);
}
settings.Properties.ClientSideEvents.SelectedIndexChanged = "function(s, e) { UpdateButtonState(); }";
settings.Properties.EnableClientSideAPI = true;
settings.Width = System.Web.UI.WebControls.Unit.Pixel(350);
settings.Height = System.Web.UI.WebControls.Unit.Pixel(200);
}).GetHtml()
</td>
<td style="padding: 60px">
<div class="form-horizontal">
<div class="form-group">
<div class="col-md-4">
#Html.DevExpress().Button(settings =>
{
settings.Name = "btnMoveSelectedItemsToRight";
settings.Text = "Agregar >";
settings.ClientSideEvents.Click = "function(s, e) { AddSelectedItems(); }";
}).GetHtml()
</div>
<div class="col-md-4">
#Html.DevExpress().Button(settings =>
{
settings.Name = "btnMoveAllItemsToRight";
settings.Text = "Agregar todos >>";
settings.ClientSideEvents.Click = "function(s, e) { AddAllItems(); }";
}).GetHtml()
</div>
</div>
<div class="form-group">
<div class="col-md-4">
#Html.DevExpress().Button(settings =>
{
settings.Name = "btnMoveSelectedItemsToLeft";
settings.Text = "< Eliminar";
settings.ClientSideEvents.Click = "function(s, e) { RemoveSelectedItems(); }";
}).GetHtml()
</div>
<div class="col-md-4">
#Html.DevExpress().Button(settings =>
{
settings.Name = "btnMoveAllItemsToLeft";
settings.Text = "<< Eliminar todos";
settings.ClientSideEvents.Click = "function(s, e) { RemoveAllItems(); }";
}).GetHtml()
</div>
</div>
</div>
</td>
<td>
#Html.DevExpress().ListBox(settings =>
{
settings.Name = "lblChoosen";
settings.Properties.SelectionMode = ListEditSelectionMode.CheckColumn;
settings.Properties.ClientSideEvents.SelectedIndexChanged = "function(s,e) { UpdateButtonState(); }";
settings.Properties.EnableClientSideAPI = true;
settings.Width = System.Web.UI.WebControls.Unit.Pixel(350);
settings.Height = System.Web.UI.WebControls.Unit.Pixel(200);
}).GetHtml()
</td>
</tr>
</table>
</div>
#*<br />*#
<div style="float:right">
<input class="btn btn-sm btn-primary" type="submit" name="btnGuardar" id="btnGuardar" value="Crear" ng-click="Guardar()" />
</div>
</div>
My controllers JS:
$scope.Guardar = function () {
if (confirm('¿Está seguro de guardar los datos?')) {
$("#btnGuardar").prop('disabled', 'disabled');
$scope.MostrarMensajeOk = false;
$scope.MostrarMensajeError = false;
var nombreRegla = $("#lblNombreRegla").val();
var localesEnGrilla = $("#lblChoosenLocales").val();
var articulosEnGrilla = $("#lblChoosen").val();
//some code here
$http({
method: 'POST',
url: baseURL + 'Configuracion/CrearRegla/?Nombre=' + nombreRegla + "&Locales="+ localesEnGrilla + "&Articulos="+ articulosEnGrilla,
}).success(function (result) {
if (result != null) {
$("#btnGuardar").prop('disabled', '');
$scope.MostrarMensajeOk = false;
$scope.MostrarMensajeError = false;
$scope.volver();
}
}).error(function (data, status, headers, config) {
$("#btnGuardar").prop('disabled', '');
alert(data);
$scope.MostrarMensajeOk = false;
$scope.MostrarGrilla = false;
$('html, body').animate({ scrollTop: 0 }, 'slow');
});
};
};
What i need its get all selected items from both list, to save in my database and then work it. What can i do? Is this posible? I've trying a lot of solutions but nothing works.
Use the client-side ASPxClientListBox.GetSelectedValues method for this purpose:
#Html.DevExpress().ListBox(settings => {
settings.Name = "lblChoosenLocales";
}).GetHtml()
var selectedValues = lblChoosenLocales.GetSelectedValues();
alert(selectedValues);
can someone explain me why this execute only first time? It should remove item from minishopping cart, but it works only first time.
This is html section:
<div data-itemid="#item.Id" class="item #(i == 0 ? "first" : null) row">
<div class="remove">
<input class="remove-item-cart-btn" type="button" value="Remove" data-itemid="#item.Id" />
</div>
I have Action in my controler:
[HttpPost]
public ActionResult RemoveProductFromCart_Catalog(int id)
{
var shoppingCartItem = _workContext.CurrentCustomer.ShoppingCartItems
.Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart && sci.Id == id)
.LimitPerStore(_storeContext.CurrentStore.Id).FirstOrDefault();
_shoppingCartService.DeleteShoppingCartItem(shoppingCartItem, ensureOnlyActiveCheckoutAttributes: true);
//display notification message and update appropriate blocks
var updatetopcartsectionhtml = string.Format(_localizationService.GetResource("ShoppingCart.HeaderQuantity"),
_workContext.CurrentCustomer.ShoppingCartItems
.Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
.LimitPerStore(_storeContext.CurrentStore.Id)
.ToList()
.GetTotalProducts());
var updateflyoutcartsectionhtml = _shoppingCartSettings.MiniShoppingCartEnabled
? this.RenderPartialViewToString("FlyoutShoppingCart", PrepareMiniShoppingCartModel())
: "";
return Json(new
{
success = true,
message = string.Format(_localizationService.GetResource("Products.ProductHasBeenAddedToTheCart.Link"), Url.RouteUrl("ShoppingCart")),
updatetopcartsectionhtml = updatetopcartsectionhtml,
updateflyoutcartsectionhtml = updateflyoutcartsectionhtml
});
}
and this is js function:
$(function() {
$(".mini-shopping-cart").on("click", '.remove-item-cart-btn', function (e)
{
alert("test");
var $this = $(this);
$.ajax({
url: '#Url.Action("RemoveProductFromCart_Catalog", "ShoppingCart")',
cache: false,
data:
{
id: $this.data('itemid')
},
success: function (data, textStatus, jqXHR)
{
$("#flyout-cart").replaceWith(data.updateflyoutcartsectionhtml);
jQuery.each($(".cart-qty"), function (i, val) {
$(val).text(data.updatetopcartsectionhtml);
});
}
});
e.preventDefault();
});
});
I am new in js so dont blame me(a lot).
Thanks in advance!
This is the whole html section:
<div id="flyout-cart" class="flyout-cart">
<div class="mini-shopping-cart">
<div class="count">
#if (Model.TotalProducts == 0)
{
#T("ShoppingCart.Mini.NoItems")
}
else
{
#Html.Raw(string.Format(T("ShoppingCart.Mini.ItemsText").Text, string.Format("{1}", Url.RouteUrl("ShoppingCart"), string.Format(T("ShoppingCart.Mini.Items").Text, Model.TotalProducts))))
}
</div>
#if (Model.TotalProducts > 0)
{
<div class="items">
#for (int i = 0; i < Model.Items.Count; i++)
{
var item = Model.Items[i];
<div data-itemid="#item.Id" class="item #(i == 0 ? "first" : null)">
#if (Model.ShowProductImages)
{
<div class="picture">
<a href="#Url.RouteUrl("Product", new { SeName = item.ProductSeName })" title="#item.Picture.Title">
<img alt="#item.Picture.AlternateText" src="#item.Picture.ImageUrl" title="#item.Picture.Title" />
</a>
</div>
}
<div class="product">
<div class="name">
#item.ProductName
</div>
#if (!String.IsNullOrEmpty(item.AttributeInfo))
{
<div class="attributes">
#Html.Raw(item.AttributeInfo)
</div>
}
<div class="price">#T("ShoppingCart.Mini.UnitPrice"): <span>#item.UnitPrice</span></div>
<div class="quantity">#T("ShoppingCart.Mini.Quantity"): <span>#item.Quantity</span></div>
</div>
<div class="remove">
<input class="remove-item-cart-btn" type="button" value="Remove" data-itemid="#item.Id" />
</div>
</div>
}
</div>
<div class="totals">#T("ShoppingCart.Totals.SubTotal"): <strong>#Model.SubTotal</strong></div>
<div class="buttons">
#if (Model.DisplayShoppingCartButton)
{
<input type="button" value="#T("ShoppingCart.Mini.ViewCart")" class="button-1 cart-button" onclick="setLocation('#(Url.RouteUrl("ShoppingCart"))')" />
}
#if (Model.DisplayCheckoutButton)
{
var checkoutUrl = "";
if (Model.AnonymousCheckoutAllowed && Model.CurrentCustomerIsGuest)
{
checkoutUrl = Url.RouteUrl("LoginCheckoutAsGuest", new { returnUrl = Url.RouteUrl("ShoppingCart") });
}
else
{
checkoutUrl = Url.RouteUrl("Checkout");
}
<input type="button" value="#T("Checkout.Button")" class="button-1 checkout-button" onclick="setLocation('#checkoutUrl')" />
}
</div>
}
</div>