I tried unobtrusiveValidation and that is not working for me, it's always breaking on
var unobtrusiveValidation = $form.data('unobtrusiveValidation');
var validator = $form.validate();
And every other solution online for partial view is not working, so what am I doing wrong?
View :
//BUNCH OF HTML
<!-- Modal edit user-->
#Html.Partial("~/Views/User/Partials/ProfileEditUserPartial.cshtml", Model.UserProfileData)
<div id="profileFormContainer" data-url="#Url.Action("ActionName", "ControllerName")"></div>
Partial view:
#model Web.Models.Users.Partials.ProfileEditUserPartialViewModel
<div class="modal fade text-left" id="profileEditUserModalId" tabindex="-1" role="dialog" aria-labelledby="myModalLabel1" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
#using (Html.BeginForm("UpdateUserData", "User", FormMethod.Post,new { id = "profileForm"}))
{
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel1">Edit</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
#Html.LabelFor(x => x.UserProfile.FirstName)*
#Html.TextBoxFor(x => x.UserProfile.FirstName, new { #class = "form-control" })
#Html.ValidationMessageFor(x => x.UserProfile.FirstName)
#Html.LabelFor(x => x.UserProfile.LastName)*
#Html.TextBoxFor(x => x.UserProfile.LastName, new { #class = "form-control" })
#Html.ValidationMessageFor(x => x.UserProfile.LastName)
#Html.LabelFor(x => x.UserProfile.Country)*
#Html.TextBoxFor(x => x.UserProfile.Country, new { #class = "form-control" })
#Html.ValidationMessageFor(x => x.UserProfile.Country)
</div>
<div class="modal-footer">
<button type="button" class="btn grey btn-outline-secondary" data-dismiss="modal">#Resources.Resource.General_Close</button>
<button type="button" class="btn btn-outline-success" data-addressId id="saveUserDataId">#Resources.Resource.General_Ok</button>
</div>
}
</div>
</div> </div>
Controller:
public ActionResult UpdateUserData(ProfileEditUserPartialViewModel userModel)
{
var model = PopulateProfileViewModel();
if (!ModelState.IsValid)
{
return PartialView("~/Views/User/Partials/ProfileEditUserPartial.cshtml", userModel);
}
m_UserService.UpdateUserProfile(userModel.UserProfile, GetUser().Id);
m_AccountService.ClearUserCache(GetUser());
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
Controller is like this because I was working with Ajax.beginForm, but let it be like this, that can be changed easily, and most important part is script file
Script:
$('#editUserDataId').click(function () {
$("#profileEditUserModalId").modal("show");
});
$('#saveUserDataId').click(function(){
var $formContainer = $('#profileFormContainer');
var url = $formContainer.attr('data-url');
$formContainer.load(url, function () {
var $form = $('#profileForm')
.removeData("validator")
.removeData("unobtrusiveValidation");
var unobtrusiveValidation = $form.data('unobtrusiveValidation');
var validator = $form.validate();
$.validator.unobtrusive.parse($form);
$form.submit(function () {
var $form = $(this);
if ($form.valid()) {
$.ajax({
url: url,
async: true,
type: 'POST',
data: JSON.stringify("Your Object or parameter"),
beforeSend: function (xhr, opts) {
},
contentType: 'application/json; charset=utf-8',
complete: function () { },
success: function (data) {
$form.html(data);
$form.removeData('validator');
$form.removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse($form);
}
});
}
return false;
});
});
return false;
});
So, I changed partial view:
<div class="modal-dialog" role="document">
<div id="profileInnerDivId" class="modal-content">
#using (Ajax.BeginForm("EditUserAddress", "User", new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "UserAddressUpdated",
InsertionMode = InsertionMode.Replace
}, new { data_accountid= #Model.AddressId }))
{
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel1">Edit</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
#Html.HiddenFor(x => x.AddressId)
#Html.LabelFor(x => x.Active)
#Html.RadioButtonFor(x => x.Active, true, new { #class = "opacity-fixed" })
</div>
<div class="modal-footer">
<button type="button" class="btn grey btn-outline-secondary" data-dismiss="modal">#Resources.Resource.General_Close</button>
<button type="submit" class="btn btn-outline-success" data-addressId id="saveEditBtnId">#Resources.Resource.General_Ok</button>
</div>
}
</div>
</div>
And in controller I am using Json:
[HttpPost]
public ActionResult EditUserAddress(UserAddress userAddress)
{
var model = PopulateProfileViewModel();
if (!ModelState.IsValid)
{
return PartialView("~/Views/User/Partials/_ProfileEditUserAddressPartial.cshtml", userAddress);
}
//some code...
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
And finally in my script I have swal that will be triggered and u just need to use HTML function to put code that is returned from action if error is occurred, so error msg will be displayed:
function UserAddressUpdated(result) {
var id = $(this).data('accountid');
if (result.success) {
$("#profileModalId").modal("hide");
swal({
title: Localization.Edit_User_Address_Success_Message,
icon: "success"
}).then(function () {
location.reload();
});
} else {
$("#profileModalId-" + id).html(result);
swal({
title: Localization.Edit_User_Address_Error_Message,
icon: "error"
});
}
}
Concept:
1. Use Ajax.BeginForm, define Success method
2. In Action use Json return type and if error occurred, return that
partial view
3. Use $('divId').html to write your msg.
Related
here my goal is to create a tree on button click one popup modal has to opent where i have to input the values and and has to store in database and as well show in the tree,and also in the context menu which node we select there also an popup modal to open and get node ,delete node and renaming has to happen
here its my controller view
public class HomeController : Controller
{
private readonly ApplicationDbContext _db;
public HomeController(ApplicationDbContext db)
{
_db = db;
}
public IActionResult Index()
{
return View();
}
//[HttpPost]
//public IActionResult Index(string selectedItems)
//{
// List<TreeViewModel> items=JsonConvert.DeserializeObject<List<TreeViewModel>>(selectedItems);
// return RedirectToAction("Index");
//}
public IActionResult GetTree()
{
List<TreeViewModel> nodes = new List<TreeViewModel>();
foreach (ParentClass type in _db.parent)
{
nodes.Add(new TreeViewModel
{
id = type.Id.ToString(),
parent = "#",
text = type.ParentName
});
}
foreach (ChildClass list in _db.child)
{
nodes.Add(new TreeViewModel
{
id = list.Id.ToString(),
parent = list.parentId.ToString(),
text = list.ChildName
});
}
return Json(nodes);
}
[HttpGet]
public IActionResult Create()
{
ParentClass parent = new ParentClass();
return PartialView("_HomePartial",parent);
}
[HttpPost]
public IActionResult Create(ParentClass parent)
{
if (ModelState.IsValid)
{
_db.parent.Add(parent);
_db.SaveChanges();
return PartialView("_HomePartial", parent);
}
return RedirectToAction("Index");
}
}
and my index view where i am giving button for popup modal to insert tree node in my code it taking only parent
<div class="container" id="placeHolder">
<div class="row">
<div class="col-3">
<div class="row pt-3">
<div class="col-6">
<p class="text-primary text-light">File Structure
</p>
</div>
<div class="col-6 text-end">
<button type="button" class="btn btn-primary"
data-toggle="ajax-modal" data-bs-target="#Addnode"
data-url="#Url.Action("Create")"><i class="bi
bi-plus-square-fill"></i></button>
</div>
</div>
<div id="simpleJsTree">
</div>
</div>
<div class="col=9">
</div>
</div>
</div>
javacript for tree view
$(document).ready(function () {
$.ajax({
async: true,
type: "GET",
url: "https://localhost:44376/Home/GetTree",
dataType: "json",
success: function (json) {
createJSTree(json);
}
});
});
function createJSTree(jsondata) {
$('#simpleJsTree').jstree({
"core": {
"check_callback": true,
'data': jsondata
},
"plugins": ["contextmenu"],
"contextmenu": {
"items": function ($node) {
var tree = $("#simpleJsTree").jstree(true);
return {
"Create": {
"separator_before": false,
"separator_after": true,
"label": "Create",
"action": function (obj) {
tree.create_node($node);
}
},
"Rename": {
"separator_before": false,
"separator_after": false,
"label": "Rename",
"action": function (obj) {
tree.edit($node);
}
},
"Remove": {
"separator_before": false,
"separator_after": false,
"label": "Remove",
"action": function (obj) {
tree.delete_node($node);
}
},
"Upload": {
"seperator_beore": false,
"seperator_after": false,
"label": "Upload"
}
};
}
}
}).bind('create_node.jstree', function (e, data) {
$.ajax({
url: "/Home/Create",
method: "POST",
data: data,
success: function (data) {
console.log(data);
}
});
});
}
here binding of create function to context menu is not working
this is the partial view where i m calling modal popup to take parent node
#model ParentClass
<div class="modal fade" id="Addnode">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"id="Addnode">Add Node</h4>
<button type="button" class="close" data-bs-
dismiss="modal">
<span>X</span>
</button>
</div>
<div class="modal-body">
<form asp-controller="Home" asp-action="Create"
method="post">
#Html.HiddenFor(m=>m.Id)
<div class="form-group">
<label asp-for="ParentName"></label>
<input asp-for="ParentName"class="form-
control" />
<span asp-validation-
for="ParentName"class="text-danger"></span>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary"
data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary"
data-save="modal">Save</button>
</div>
</div>
</div>
</div>
and site.js file to show modal popup
$(function () {
var placeElement = $('#placeHolder');
$('button[data-toggle="ajax-modal"]').click(function (event) {
var url = $(this).data('url');
$.get(url).done(function (data) {
placeElement.html(data);
placeElement.find('.modal').modal('show');
});
});
placeElement.on('click', '[data-save="modal"]', function
(event) {
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var sendData = form.serialize();
$.post(actionUrl, sendData).done(function (data) {
placeElement.find('.modal').modal('hide');
});
});
});
You are making ajax call with the codes:
var sendData = form.serialize();
$.post(actionUrl, sendData)
controller in MVC project read data from request form by default,So you need to add
[FromBody]
[HttpPost]
public IActionResult Create([FromBody]ParentClass parent)
{
_db.parent.Add(parent);
_db.SaveChanges();
return PartialView("_HomePartial", parent);
}
if you have further issue on the case,please show more details of the error
I am using Html.BeginForm to submit my form and Html.ValidationSummary for validating. Now I would like to do an action in javascript (launch a reload animation) only if the form is submitted succesfully. My problem is, that the action is fired even when the form of the validation is is not validated successfully. Is it possible to find out if the validation was successful or not?
Here is my code:
#using (Html.BeginForm("AddRequest", "Manage", FormMethod.Post, new { id="addRequest"}))
{
<div class="modal-body">
<div>#Html.ValidationSummary(false, "", new { id = "requestValidationSummary" #*onsubmit = "return viewNewRequestLoader()"*# })</div>
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(m => m.DateFrom, "Datum od:", new { id = "labelReqDateFrom" })
#Html.TextBoxFor(m => m.DateFrom, new { #class = "date-picker form-control", Value = "", type = "date", id = "requestDateFrom" })
#Html.LabelFor(m => m.DateTo, "Datum do:", new { id = "labelReqDateTo" })
#Html.TextBoxFor(m => m.DateTo, new { #class = "date-picker form-control", Value = "", type = "date", id = "requestDateTo" })
#Html.LabelFor(m => m.Description, "Popis:")
#Html.TextBoxFor(m => m.Description, new { #class = "form-control", Value = "", Id = "RequestDescription" })
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-dismiss="modal">Zavřít</button>
<button type="submit" class="btn btn-primary">Potvrdit</button>
</div>
}
and js code:
$("#addRequest").submit(function (event) {
$('.modal').modal('hide');
$("#ajaxLoader").fadeIn(300);
});
As you can see below, I have a modal that should be validated then send a request to the server. The problem is that if I try to submit for the first time, that validation is worked properly but for the second time it won't work. When I debug the codes I found out that validationCheck() worked fine but the resolve() doesn't return any result to the add() in certificate-manager file.
request.js
let insert = function (isPost = false, url, data, reloadLocation = false, table = null,
modal = null, ponds) {
let request = null;
if (isPost) {
let uploadNotify = uploadNotification();
//step 3
let config = {
onUploadProgress: function (progressEvent) {
let percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
console.log(percentCompleted);
uploadNotify.update('message', '<strong>Uploading</strong> ' + percentCompleted + ' %');
uploadNotify.update('progress', percentCompleted);
},
headers: {
'content-type': 'multipart/form-data'
}
};
//step 4
request = axios.post(url, data, config)
} else {
//step 4
request = axios.get(url, {
params: data
});
}
request.then(function (response) {
console.log(response);
let data = response['data'];
if (data['status'] === 200) {
let content = {
'title': 'Done!',
'message': data['message']
};
notification(content, 1);
if (reloadLocation)
location.reload();
if (table) {
table.ajax.reload();
clearModal('.inp', ponds);
}
}
})
.catch(function (error) {
console.log(error);
let data = error['data'];
let content = {
'title': 'Error!',
'message': data['message']
};
notification(content, 0);
})
.then(function () {
if (modal)
closeModal(modal);
});
};
utilities.js
async function validationCheck (id, rules) {
jQuery.validator.addMethod('passwordCheck', function (value, element, param) {
//Your Validation Here
let oldPass = jQuery('#input-old-password').val();
let confirmPass = jQuery('#input-confirm-password').val();
return oldPass != null && confirmPass === value;
// return bool here if valid or not.
}, 'Your error message!');
jQuery.validator.addMethod('phoneNumber', function (value, element, param) {
value = value.replace(/\s+/g, "");
return this.optional(element) || value.length > 9 &&
value.match(/\(?([0-9]{3})\)?([ .-]?)([0-9]{3})\2([0-9]{4})/);
}, 'Please specify a valid phone number');
jQuery.validator.addMethod('startDate', function (value, element, param) {
return (parseInt(value) > 2000)
}, 'Please specify a valid year');
jQuery.validator.addMethod('endDate', function (value, element, param) {
return (parseInt(value) >= parseInt(jQuery('#input-start-time').val()) ||
jQuery('#input-current').is(":checked"))
}, 'Please specify a valid year');
jQuery.validator.addMethod('uendDate', function (value, element, param) {
return (parseInt(value) >= parseInt(jQuery('#input-update-start-time').val()) ||
jQuery('#input-update-current').is(":checked"))
}, 'Please specify a valid year');
return new Promise((resolve, reject)=> {
jQuery(id).validate({
// define validation rules
rules: rules,
errorPlacement: function (error, element) {
let group = element.closest('.input-group');
if (group.length) {
group.after(error.addClass('invalid-feedback'));
} else {
element.after(error.addClass('invalid-feedback'));
}
},
// messages: {
// username: {
// required: "Username is required"
// }
// },
//display error alert on form submit
invalidHandler: function (event, validator) {
// let alert = jQuery('#kt_form_1_msg');
// alert.removeClass('kt--hide').show();
KTUtil.scrollTo(id, -200);
reject(false);
},
submitHandler: function (form) {
resolve(true);
//form[0].submit(); // submit the form
}
});
});
}
certificate-manager.js
let add = async function () {
let check = await validationCheck("#form", {
title: {
required: true
},
company: {
required: true
},
start: {
required: true,
date: true,
digits: true,
minlength: 4,
maxlength: 4,
startDate: true
},
end: {
date: true,
digits: true,
minlength: 4,
maxlength: 4,
endDate: true
},
description: {
required: true
}
}).then(value => {
console.log(value)
insert(
false,
'/api/add/certificate',
getInputsData(),
false,
table,
"#kt_modal")
}, reason => {
console.log(reason)
}).catch(reason => {
console.log(reason)
});
}
<!--begin:: insert Modal-->
<div class="modal fade" id="kt_modal" tabindex="-1" role="dialog"
aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">New Certificate</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
</button>
</div>
<div class="modal-body">
<form id="form">
<div class="row">
<div class="col-12">
<div class="form-group">
<label for="input-title"
class="form-control-label">Title</label>
<input type="text" class="inp form-control"
name="title"
id="input-title">
</div>
<div class="form-group">
<label for="input-company-institute"
class="form-control-label">Company/Institute</label>
<input type="text" class="inp form-control" name="company" id="input-company-institute">
</div>
<div class="row">
<div class="form-group col-6">
<label for="input-start-time"
class="form-control-label">From Year</label>
<input type="text" class="inp form-control" name="start" id="input-start-time">
</div>
<div class="form-group col-6">
<label for="input-end-time"
class="form-control-label">To Year</label>
<input type="text" class="inp form-control" name="end" id="input-end-time">
<div class="mt-2">
<label for="input-current" class="kt-checkbox kt-checkbox--brand col-6">
<input type="checkbox" id="input-current"> Current
<span></span>
</label>
</div>
</div>
</div>
<div class="form-group">
<label for="input-description"
class="form-control-label">Description</label>
<textarea class="inp form-control" name = "description" id="input-description"></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button id="add-btn" onclick="add()" type="submit" class="btn btn-primary" >Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!--end::insert Modal-->
the order of the files is:
'../../../assets/adminPanel/js/utilities.js',
'../../../assets/adminPanel/js/request.js',
'../../../assets/adminPanel/js/pages/resume/certificate-manager.js'
No matter what I try none of javascript methods is not firing/working.
[HttpPost]
public JsonResult Errors (string name, string email)
{
//send email
return new JsonResult()
{
Data = new { result = "success" },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
Partial View
#using (Ajax.BeginForm(
"Errors",
"Home",
new AjaxOptions {
HttpMethod = "POST",
OnSuccess = "onSuccess ",
OnFailure = "OnFailure",
OnBegin = "Begin()" },
new { #class = "form-horizontal", id = "error-form" }))
{
#Html.AntiForgeryToken()
<div class="form-group">
<label>Your name</label>
<input type="text" name="name" class="form-control" value="#name" />
</div>
<div class="form-group">
<label>Your e-mail</label>
<input type="text" name="email" class="form-control" value="#email" />
</div>
<button class="btn btn-success" type="submit" style="margin-bottom:4em;">Send message</button>
}
<div class="form-group" id="thankYou" style="display:none">
<label>Thank you!</label>
</div>
</div>
</div>
</div>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript">
function Begin() {
alert("b");
}
function onSuccess(data) {
debugger;
alert(data.result);
};
function OnFailure(data) {
debugger;
alert(data.result);
};
$(document).ready(function () {
});
</script>
All I get is a response in JSON format. See screenshot. No event is fired. Any ideas?
Ajax.BeginForm has 11 overloads... your parameters does't match any of them. I assume you want to use this overload:
BeginForm(AjaxHelper, String, String, RouteValueDictionary, AjaxOptions, IDictionary<String,Object>)
You need to add RouteValueDictionary to your parameters:
#using (Ajax.BeginForm(
"Errors", // <--action name
"Home", // <--controller
null, // <-- RouteValueDictionary
new AjaxOptions { // <-- AjaxOptions
HttpMethod = "POST",
OnSuccess = "onSuccess ",
OnFailure = "OnFailure",
OnBegin = "Begin()" },
new { // <-- htmlAttributes
#class = "form-horizontal",
id = "error-form" }))
I trying to build a CRUD using Vue.js and Laravel, but... I can Save, Read and Update the only problem is the Delete, can someone help me?
My index.blade.php: (to get id)
<div class="modal inmodal" id="delete" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content animated bounceInRight">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Fechar</span></button>
<h4 class="modal-title">Delete</h4>
</div>
<div class="modal-body">
<div class="form-group">
<p>Do you want delete this row <strong>ID: </strong> #{{competency.id}} <strong>Nome: </strong> #{{competency.name}} </p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger" v-on:click="remove(competency.id)">Delete</button>
</div>
</div>
</div>
My Vue.js
var competency = new Vue({
el: '#competency',
filters: {
moment: function (date) {
return moment(date).format('DD/MM/YYYY');
}
},
data: {
competency: "",
searchQuery: '',
search: {
name: ""
},
list: [],
},
methods: {
fillCompetency: function(comp){
if (comp == null)
this.competency = {
id : "",
name : "",
description : "",
}
else
this.competency = comp;
},
del: function(index){
this.fillCompetency(this.list[index]);
$("#delete").modal('show');
},
remove: function(id){
var self = this;
self.competency._token = window.Laravel.csrfToken;
$.ajax({
url: "competency",
type: "POST",
dataType: 'json',
traditional: true,
data: id
}).done(function(data){
self.filter();
$("#delete").modal('hide');
fillCompetency(null);
});
}
},
mounted: function () {
this.filter();
},
watch: {
}
});
My Controller
class CompetencyController extends Controller {
public function __construct(){
$this -> middleware('auth');
}
public function index(){
return view('competency/index');
}
public function filter(){
$list = Competency::all();
return response()->json($list);
}
public function create(){
}
public function store(Request $request){
$entity = new Competency;
if ($request->id != null){
$entity = Competency::find($request->id);
}
if ($request->name == null && $request->description == null){
$entity = Competency::find($id);
return response()->json($entity->delete());
}
$entity->name = $request->name;
$entity->description = $request->description;
return response()->json($entity->save());
}
public function delete($id){
$entity = new Competency;
$entity = Competency::find($id);
return response()->json($entity->delete());
}
public function show($id){
}
public function edit($id){
}
public function update(Request $request){
}
public function destroy($id){
$entity = new Competency;
$entity = Competency::find($id);
return response()->json($entity->delete());
}
}
My route:
Route::resource('competency', 'CompetencyController');
The problem is, i have tried to send DELETE method on remove from Vue, but i get an error called 500 (Internal Error Serve) but on laravel.log dont show anything, i have tried send DELETE method because the desroy method is called correct? so i get error instead i send by POST method to store and check if just id is not null, if not i called method delete by laravel, so any method that i hev tried dont work, can someone help me?
I think that the error is on Route, but i tried everything too
Try changing your delete method to this
// your route for delete should be
Route::delete('competency/{id}', 'Controller#delete');
// controller
public function delete($id){
$responseMsg = "Competency not found";
$status = 404;
$entity = Competency::find($id);
if ($entity != null ){
$responseMsg = "Competency deleted";
$status = 204;
$entity->delete(); // delete method is void, doen't return any value
}
return response()->json(['message' => $responseMsg], $status);
}
Vue.js remove method
remove: function(id){
var self = this;
self.competency._token = window.Laravel.csrfToken;
$.ajax({
url: "competency/"+id,
type: "DELETE", //
traditional: true
// if you use POST method, data has to be a json object
// {id: id} then in laravel you could do $request->input('id');
}).done(function(data){
self.filter();
$("#delete").modal('hide');
fillCompetency(null);
});
}