Use custom constraint in bootstrapValidator - asp.net-mvc

I want to add some custom constraint to password validation. I want it to have at least a Lowercase and an uppercase and a digit.
<form id="userForm">
<input type="hidden" class="form-control" id="ID" />
<div class="row">
<div class="col-sm-12 col-md-6 col-lg-6">
<div class="form-group">
<label for="FName">First Name</label>
<input type="text" class="form-control" id="FName" name="FName" />
</div>
</div>
<div class="col-sm-12 col-md-6 col-lg-6">
<div class="form-group">
<label for="LName">Last Name</label>
<input type="text" class="form-control" id="LName" name="LName" />
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-6 col-lg-6">
<div class="form-group">
<label for="UserName">User Name </label>
<input type="text" class="form-control" id="UserName" name="UserName" />
</div>
</div>
<div class="col-sm-12 col-md-6 col-lg-6">
<div class="form-group">
<label for="Password">Password </label>
<input type="password" class="form-control" id="Password" name="Password" />
</div>
</div>
</div>
</form>
<script type="text/javascript">
$('#userForm').bootstrapValidator({
message: 'This value is not valid',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
submitHandler: function (validator, form, submitButton) {
},
fields: {
FName: {
validators: {
notEmpty: {
message: 'Required!'
}
}
},
LName: {
validators: {
notEmpty: {
message: 'Required!'
}
}
},
UserName: {
validators: {
notEmpty: {
message: 'Required!'
}
},
stringLength: {
min: 3,
max: 25,
message: 'Length should be between 3 to 25.'
},
},
Password: {
validators: {
notEmpty: {
message: 'Required!'
},
stringLength: {
min: 8,
max: 15,
message: 'Length should be between 8 to 15.'
}
}
},
}
});
</script>

I used callback at last:
$('#userForm').bootstrapValidator({
message: 'This value is not valid',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
submitHandler: function (validator, form, submitButton) {
},
excluded: [':disabled'],
fields: {
FName: {
validators: {
notEmpty: {
message: 'Required!'
}
}
},
LName: {
validators: {
notEmpty: {
message: 'Required!'
}
}
},
UserName: {
validators: {
notEmpty: {
message: 'Required!'
},
stringLength: {
min: 3,
max: 25,
message: 'Length should be between 3 to 25.'
}
}
},
Password: {
validators: {
notEmpty: {
message: 'Required!'
},
stringLength: {
min: 8,
max: 15,
message: 'Length should be between 8 to 5.'
},
callback: {
callback: function (value, validator, $field) {
var validv = true;
var messagev = '';
//Number
if (!value.match(/\d/)) {
validv = false;
messagev += 'Enter a number.<br />'
}
//Lowercase letter
if (!value.match(/[A-z]/)) {
validv = false;
messagev += 'Enter a lowercase charachter..<br />'
}
//Capital letter
if (!value.match(/[A-Z]/)) {
validv = false;
messagev += 'Enter a capital charachter.'
}
return {
valid: validv,
message: messagev
}
}
}
}
},
selectStatus: {
validators: {
notEmpty: {
message: 'Required!'
}
}
}
}
});

You can use below code for validation of password for Upper case, Lower case, and digit.
Where Value = field name you can add this code into Password Field.
// The password doesn't contain any uppercase character
if (value === value.toLowerCase()) {
return {
valid: false,
message: 'The password must contain at least one upper case character'
}
}
// The password doesn't contain any uppercase character
if (value === value.toUpperCase()) {
return {
valid: false,
message: 'The password must contain at least one lower case character'
}
}
// The password doesn't contain any digit
if (value.search(/[0-9]/) < 0) {
return {
valid: false,
message: 'The password must contain at least one digit'
}
}

Related

i need help on using post in asp.net mvc swet allert

I post the data in the first screenshot. And I'm warning you to wait on the button. In the second picture, I print on the screen that the registration has been completed successfully.
But I cannot transfer the data to the database.
For these screens, I am using js file in the back part.
I haven't been able to solve the problem. can you help me ?
<form class="form fv-plugins-bootstrap5 fv-plugins-framework" action="#" id="kt_modal_add_customer_form" data-kt-redirect="/Dashboard/Cari">
<!--begin::Modal header-->
<div class="modal-header" id="kt_modal_add_customer_header">
<!--begin::Modal title-->
<h2 class="fw-bolder">Yeni Cari</h2>
<!--end::Modal title-->
<!--begin::Close-->
<div id="kt_modal_add_customer_close" class="btn btn-icon btn-sm btn-active-icon-primary">
<!--begin::Svg Icon | path: icons/duotune/arrows/arr061.svg-->
<span class="svg-icon svg-icon-1">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<rect opacity="0.5" x="6" y="17.3137" width="16" height="2" rx="1" transform="rotate(-45 6 17.3137)" fill="black"></rect>
<rect x="7.41422" y="6" width="16" height="2" rx="1" transform="rotate(45 7.41422 6)" fill="black"></rect>
</svg>
</span>
<!--end::Svg Icon-->
</div>
<!--end::Close-->
</div>
<!--end::Modal header-->
<!--begin::Modal body-->
<div class="modal-body py-10 px-lg-17">
<!--begin::Scroll-->
<div class="scroll-y me-n7 pe-7" id="kt_modal_add_customer_scroll" data-kt-scroll="true" data-kt-scroll-activate="{default: false, lg: true}" data-kt-scroll-max-height="auto" data-kt-scroll-dependencies="#kt_modal_add_customer_header" data-kt-scroll-wrappers="#kt_modal_add_customer_scroll" data-kt-scroll-offset="300px" style="max-height: 397px;">
<!--begin::Input group-->
<div class="fv-row mb-7 fv-plugins-icon-container">
<!--begin::Label-->
<label class="required fs-6 fw-bold mb-2">Cari Kodu</label>
<!--end::Label-->
<!--begin::Input-->
<input type="text" class="form-control form-control-solid" placeholder="" name="CariKodu" value="#ViewData["CariKodu"]">
<!--end::Input-->
<div class="fv-plugins-message-container invalid-feedback"></div>
</div>
<!--end::Input group-->
<!--begin::Input group-->
<div class="fv-row mb-7 fv-plugins-icon-container">
<!--begin::Label-->
<label class="required fs-6 fw-bold mb-2">Firma Ünvanı</label>
<!--end::Label-->
<!--begin::Input-->
<input type="text" class="form-control form-control-solid" placeholder="" name="FirmaUnvani">
<!--end::Input-->
<div class="fv-plugins-message-container invalid-feedback"></div>
</div>
<!--end::Input group-->
<!--begin::Input group-->
<div class="fv-row mb-7 fv-plugins-icon-container">
<!--begin::Label-->
<label class="required fs-6 fw-bold mb-2">Ticari Ünvan</label>
<!--end::Label-->
<!--begin::Input-->
<input type="text" class="form-control form-control-solid" placeholder="" name="TicariUnvani">
<!--end::Input-->
<div class="fv-plugins-message-container invalid-feedback"></div>
</div>
<!--end::Input group-->
<!--begin::Input group-->
<div class="fv-row mb-7 fv-plugins-icon-container">
<!--begin::Label-->
<label class="fs-6 fw-bold mb-2">
<span class="required">E-Posta</span>
<i class="fas fa-exclamation-circle ms-1 fs-7" data-bs-toggle="tooltip" title="" data-bs-original-title="Aktivasyon için E-Posta Adresi Zorunludur" aria-label="Aktivasyon için E-Posta Adresi Zorunludur"></i>
</label>
<!--end::Label-->
<!--begin::Input-->
<input type="email" class="form-control form-control-solid" placeholder="" name="EPosta">
<!--end::Input-->
<div class="fv-plugins-message-container invalid-feedback"></div>
</div>
<!--end::Input group-->
<!--begin::Input group-->
<div class="fv-row mb-7 fv-plugins-icon-container">
<!--begin::Label-->
<label class="required fs-6 fw-bold mb-2">Vergi Dairesi</label>
<!--end::Label-->
<!--begin::Input-->
<input type="text" class="form-control form-control-solid" placeholder="" name="VDairesi">
<!--end::Input-->
<div class="fv-plugins-message-container invalid-feedback"></div>
</div>
<!--end::Input group-->
<!--begin::Input group-->
<div class="fv-row mb-7 fv-plugins-icon-container">
<!--begin::Label-->
<label class="required fs-6 fw-bold mb-2">Vergi Numarası</label>
<!--end::Label-->
<!--begin::Input-->
<input type="text" class="form-control form-control-solid" placeholder="" name="VNo">
<!--end::Input-->
<div class="fv-plugins-message-container invalid-feedback"></div>
</div>
<!--end::Input group-->
</div>
<!--end::Scroll-->
</div>
<!--end::Modal body-->
<!--begin::Modal footer-->
<div class="modal-footer flex-center">
<!--begin::Button-->
<button type="reset" id="kt_modal_add_customer_cancel" class="btn btn-light me-3">İptal</button>
<!--end::Button-->
<!--begin::Button-->
<button type="submit" id="kt_modal_add_customer_submit" class="btn btn-primary">
<span class="indicator-label">Gönder</span>
<span class="indicator-progress">
Lütfen Bekleyiniz...
<span class="spinner-border spinner-border-sm align-middle ms-2"></span>
</span>
</button>
<!--end::Button-->
</div>
<!--end::Modal footer-->
<div></div>
</form>
<!--end::Form-->
"use strict";
var KTModalCustomersAdd = function () {
var t, e, o, n, r, i;
return {
init: function () {
i = new bootstrap.Modal(document.querySelector("#kt_modal_add_customer")), r = document.querySelector("#kt_modal_add_customer_form"), t = r.querySelector("#kt_modal_add_customer_submit"), e = r.querySelector("#kt_modal_add_customer_cancel"), o = r.querySelector("#kt_modal_add_customer_close"), n = FormValidation.formValidation(r, {
fields: {
CariKodu: {
validators: {
notEmpty: {
message: "Firmanın Cari Kodu Olmadan Kayıt Açamazsınız."
}
}
},
FirmaUnvani: {
validators: {
notEmpty: {
message: "Firma Ünvanı Olmadan Kayıt Açamazsınız."
}
}
},
"TicariUnvani": {
validators: {
notEmpty: {
message: "Firmanın Ticari Ünvanı Olmadan Kayıt Açamazsınız."
}
}
},
"EPosta": {
validators: {
notEmpty: {
message: "Aktivasyon İşlemi İçin E-Posta Adresini Girmelisiniz."
}
}
},
VDairesi: {
validators: {
notEmpty: {
message: "Firmanın Vergi Dairesi Olmadan Kayıt Açamazsınız."
}
}
},
VNo: {
validators: {
notEmpty: {
message: "Firmanın Vergi Numarası Olmadan Kayıt Açamazsınız."
}
}
},
city: {
validators: {
notEmpty: {
message: "City is required"
}
}
},
state: {
validators: {
notEmpty: {
message: "State is required"
}
}
},
postcode: {
validators: {
notEmpty: {
message: "Postcode is required"
}
}
}
},
plugins: {
trigger: new FormValidation.plugins.Trigger,
bootstrap: new FormValidation.plugins.Bootstrap5({
rowSelector: ".fv-row",
eleInvalidClass: "",
eleValidClass: ""
})
}
}), $(r.querySelector('[name="country"]')).on("change", (function () {
n.revalidateField("country")
})), t.addEventListener("click", (function (e) {
e.preventDefault(), n && n.validate().then((function (e) {
console.log("validated!"), "Valid" == e ? (t.setAttribute("data-kt-indicator", "on"), t.disabled = !0, setTimeout((function () {
t.removeAttribute("data-kt-indicator"), Swal.fire({
text: "Form bilgileri başarıyla gönderildi!",
icon: "success",
buttonsStyling: !1,
confirmButtonText: "Tamam, Anladım",
customClass: {
confirmButton: "btn btn-primary"
},
}).then((function (e) {
e.isConfirmed && (i.hide(), t.disabled = !1, window.location = r.getAttribute("data-kt-redirect"))
}))
}), 2e3)) : Swal.fire({
text: "Maalesef bazı hatalar tespit edildi, lütfen tekrar deneyin.",
icon: "error",
buttonsStyling: !1,
confirmButtonText: "Tamam, Anladım!",
customClass: {
confirmButton: "btn btn-primary"
}
})
}))
})), e.addEventListener("click", (function (t) {
t.preventDefault(), Swal.fire({
text: "İptal etmek istediğinizden emin misiniz?",
icon: "warning",
showCancelButton: !0,
buttonsStyling: !1,
confirmButtonText: "Evet, Kaydı İptal Et",
cancelButtonText: "Hayır, Devam Et",
customClass: {
confirmButton: "btn btn-primary",
cancelButton: "btn btn-active-light"
}
}).then((function (t) {
t.value ? (r.reset(), i.hide()) : "cancel" === t.dismiss && Swal.fire({
text: "Formunuz iptal edilmedi!.",
icon: "error",
buttonsStyling: !1,
confirmButtonText: "Tamam, Anladım!",
customClass: {
confirmButton: "btn btn-primary"
}
})
}))
})), o.addEventListener("click", (function (t) {
t.preventDefault(), Swal.fire({
text: "İptal etmek istediğinizden emin misiniz?",
icon: "warning",
showCancelButton: !0,
buttonsStyling: !1,
confirmButtonText: "Evet, İptal Et!",
cancelButtonText: "Hayır, Devam Et",
customClass: {
confirmButton: "btn btn-primary",
cancelButton: "btn btn-active-light"
}
}).then((function (t) {
t.value ? (r.reset(), i.hide()) : "cancel" === t.dismiss && Swal.fire({
text: "Formunuz iptal edilmedi!.",
icon: "error",
buttonsStyling: !1,
confirmButtonText: "Tamam, Anladım!",
customClass: {
confirmButton: "btn btn-primary"
}
})
}))
}))
}
}
}();
KTUtil.onDOMContentLoaded((function () {
KTModalCustomersAdd.init()
}));
Controller
[HttpPost]
public JsonResult Cari(Cariler p)
{
db.Cariler.Add(p);
db.SaveChanges();
return Json(p);
}
I tried using the post structure with ajax inside the js file. I was not successful.
I have completed the sweet alert record adding process as follows. It works successfully. Topic can be closed.
console.log(e);
debugger;
var EmpModel = {
CariKodu: $("#CariKodu").val(),
FirmaUnvani: $("#FirmaUnvani").val(),
TicariUnvani: $("#TicariUnvani").val(),
EPosta: $("#EPosta").val(),
VDairesi: $("#VDairesi").val(),
Telefon1: $("#Telefon1").val(),
VNo: $("#VNo").val()
};
$.ajax({
type: "POST",
url: "/Dashboard/Cari",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(EmpModel),
success: function (msg) { },
error: function (err) { alert(err.responseText) }
})

Bind DataSource in my Grid in my ViewModel

I have my app MVC Asp.net using MVVM. I am trying to bind my grid to my ViewModel but it doesn't work. This is my sample:
My ViewModel ...
var CompanyViewModel = kendo.observable({
container: null,
tabGeneral_tbx_NamelId: "tabGeneral_tbx_Name",
tabGeneral_tbx_AddresslId: "tabGeneral_tbx_Address",
tabContactPerson_tbx_namelId: "tabContactPerson_tbx_name",
tabContactPerson_tbx_lastNamelId: "tabContactPerson_tbx_lastName",
tabContactPerson_tbx_phoneNumberlId: "tabContactPerson_tbx_phoneNumber",
tabContactPerson_tbx_workStationlId: "tabContactPerson_tbx_workStation",
tabContactPerson_tbx_emaillId: "tabContactPerson_tbx_email",
name: null,
address: null,
contactPerson_name: null,
contactPerson_lastName: null,
contactPerson_phoneNumber: null,
contactPerson_workStation: null,
contactPerson_email: null,
contactPersons: new kendo.data.DataSource(),
employees: [],
init: function (container) {
this.container = container;
kendo.bind(document.body.children, this);
this.createGridContactPersons();
//this.createTextBox();
this.bindKendoUIWidgets();
},
bindKendoUIWidgets: function () {
kendo.bind($("#grid_contactPerson"), this.contactPersons);
//kendo.bind($("#" + this.tabContactPerson_tbx_namelId), this.contactPerson_name);
},
createGridContactPersons: function () {
$("#grid_contactPerson").kendoGrid({
datasource: {
//data: new kendo.data.DataSource({ data: this.contactPersons }),
schema: {
model: {
fields: {
name: { type: "string" },
lastName: { type: "string" },
phoneNumber: { type: "string" },
workStation: { type: "string" },
email: { type: "string" }
}
}
}
},
autobind: true,
columns: [{
field: "name",
title: "Nombre",
width: 150
}, {
field: "lastName",
title: "Apellidos",
width: 270
}, {
field: "phoneNumber",
title: "Teléfono",
width: 160
}, {
field: "workStation",
title: "Puesto de Trabajo",
width: 270
}, {
field: "email",
title: "Email"
}]
});
},
createTextBox: function () {
$("#" + this.tabContactPerson_tbx_namelId).kendoText();
},
click_btnAddPersonContact: function (e) {
this.get("contactPersons").add({
name: this.get("contactPerson_name"),
lastName: this.get("contactPerson_lastName"),
phoneNumber: this.get("contactPerson_phoneNumber"),
workStation: this.get("contactPerson_workStation"),
email: this.get("contactPerson_email")
});
//this.get("contactPersons").push({
// name: this.get("contactPerson_name"),
// lastName: this.get("contactPerson_lastName"),
// phoneNumber: this.get("contactPerson_phoneNumber"),
// workStation: this.get("contactPerson_workStation"),
// email: this.get("contactPerson_email")
//});
//var grid = $("#grid_contactPerson").data("kendoGrid");
//grid.dataSource.data(this.contactPersons);
//grid.dataSource.fetch();
}
My View ...
section scripts
{
<script src="~/Content/js/Company.js"></script>
<script type="text/javascript">
$(document).ready(function () {
CompanyViewModel.init();
});
</script>
}
<div class="row">
<div class="form-group">
<label for="tabContactPerson_lbl_name" class="col-sm-4 control-label">Nombre</label>
<label for="tabContactPerson_lbl_lastName" class="col-sm-8 control-label">Apellidos</label>
</div>
<div class="form-group">
<div class="col-sm-4">
Html.Kendo().TextBox().Name("tabContactPerson_tbx_name").HtmlAttributes(new { #class = "form-control100", placeholder = "Nombre", data_bind = "value: contactPerson_name" })
</div>
<div class="col-sm-8">
Html.Kendo().TextBox().Name("tabContactPerson_tbx_lastName").HtmlAttributes(new { #class = "form-control", style = "width:100%", placeholder = "Apellidos", data_bind = "value: contactPerson_lastName" })
</div>
</div>
</div>
<br />
<div class="row">
<div class="form-group">
<label for="tabContactPerson_lbl_phoneNumber" class="col-sm-4 control-label">Teléfono</label>
<label for="tabContactPerson_lbl_workStation" class="col-sm-4 control-label">Puesto de Trabajo</label>
<label for="tabContactPerson_lbl_email" class="col-sm-4 control-label">E-mail</label>
</div>
<div class="form-group">
<div class="col-sm-4">
Html.Kendo().TextBox().Name("tabContactPerson_tbx_phoneNumber").HtmlAttributes(new { #class = "form-control", style = "width:100%", placeholder = "Teléfono", data_bind = "value: contactPerson_phoneNumber" })
</div>
<div class="col-sm-4">
Html.Kendo().TextBox().Name("tabContactPerson_tbx_workStation").HtmlAttributes(new { #class = "form-control", style = "width:100%", placeholder = "Puesto de Trabajo", data_bind = "value: contactPerson_workStation" })
</div>
<div class="col-sm-4">
Html.Kendo().TextBox().Name("tabContactPerson_tbx_email").HtmlAttributes(new { #class = "form-control", style = "width:100%", placeholder = "E-mail", data_bind = "value: contactPerson_email" })
</div>
</div>
</div>
<br />
<div class="row">
<div class="form-group">
<div class="col-sm-12">
<div id="grid_contactPerson"></div>
</div>
</div>
</div>
<br />
<div class="row">
<div class="form-group">
<div class="col-sm-2">
<input data-bind="events:{ click: click_btnAddPersonContact }" type="button" id="btnAddPersonContact" value="Agregar Persona de Contacto" />
</div>
</div>
</div>
When I AddPerson the grid does not update with the data from my DataSource. How can I bind my ViewModel to the data of the grid???
Thanks

Dynamically add multiple fields to be validated using bootstrap validator

I have gone through the example here. But it illustrates dynamic addition of a single input field. I have to add multiple dynamic input fields. How can I achieve it? Refer this example jsfiddle
I need to dynamically add all the three fields in the table row on clicking button through.
You can try somethings like this:
<form id="myForm" action="myAction">
<div class="row" id="line_1">
<div class="col-md-2 form-group">
<input type="text" class="form-control input-sm" id="idFirstField_1" name="firstField[]">
</div>
<div class="col-md-2 form-group">
<input type="text" class="form-control input-sm" id="idSecondField_1" name="secondField[]">
</div>
<div class="col-md-2 form-group">
<input type="text" class="form-control input-sm" id="idThirdField_1" name="thirdField[]">
</div>
</div>
<a id="cloneButton">add line</a>
</form>
In the JavaScript file you must to use the function clone() and to change the id of each input if you want:
$(document).ready(function () {
var count = 2;
$('#cloneButton').click(function () {
var klon = $('#line_1');
klon.clone().attr('id', 'line_' + (++count)).insertAfter($('#line_1'));
$('#line_' + count).children('div').children('input').each(function () {
$(this).val('');
var oldId = $(this).attr('id').split('_');
$(this).attr('id', oldId[0] + '_' + count);
});
});
//if you want to validate the fields, then you can use this code:
$('#myForm').bootstrapValidator({
fields: {
'firstField[]': {
validators: {
notEmpty: {
message: 'Enter a value'
}
}
},
'secondField[]': {
validators: {
notEmpty: {
message: 'Enter a value'
}
}
},
'thirdField[]': {
validators: {
notEmpty: {
message: 'Enter a value'
}
}
}
}
});
});
Now the bootstrap validation does not will work for cloned fields because you must to use in the JavaScript file somethings like this
$('#myForm').bootstrapValidator('addField', $option); //(from your link http://bootstrapvalidator.com/examples/adding-dynamic-field/ )
but who will contains all fields. I don't now how to do it.

bind kendo.data.DataSource to combo using MVVM

Again next question , this time a tricky one,
Datasource:
var dsCountryList =
new kendo.data.DataSource({
transport: {
read: {
dataType: "jsonp",
url: "/Masters/GetCountries"
}
},
schema: {
model: {
id: "CountryID",
fields: {
"CountryDesc": {
}
}
}
}
});
Observable object
function Set_MVVMSupplier() {
vmSupplier = kendo.observable({
SupplierID: 0,
SupplierName: "",
AccountNo: "",
CountryList: dsCountryList,
});
kendo.bind($("#supplierForm"), vmSupplier);
}
here is the html which is bind to observable object , but i am not getting combobox filled, also each time i clicked the combo request goes to server and bring data in json format for countryID, CountryDesc
<div class="span6">
<div class="control-group">
<label class="control-label" for="txtCountryId">Country</label>
<div class="row-fluid controls">
#*<input class="input-large" type="text" id="txtCountryId" placeholder="CountryId" data-bind="value: CountryId">*#
<select id="txtCountryId" data-role="dropdownlist"
data-text-field="CountryDesc" data-value-field="CountryID" , data-skip="true"
data-bind="source: CountryList, value: CountryDesc">
</select>
</div>
</div>
</div>
I didn't get the answer , so i found an alternate working ice of code. just have a look and if it helps then please vote.
created model for ddl in js file
ddl = kendo.data.Model.define({
fields: {
CountryId: { type: "int" },
ConfigurationID: { type: "int" }
}
});
added var ddl to MVVM js file
vmSupplier = kendo.observable({
CountryId: new ddl({ CountryId: 0 }),
ConfigurationID: new ddl({ ConfigurationID: 0 }),});
added code in controller
using (CountriesManager objCountriesManager = new CountriesManager())
{
ViewBag.Countries = new SelectList(
objCountriesManager.GetCountries().Select(p => new { p.CountryID, p.CountryDesc })
, "CountryID", "CountryDesc"); ;
}
added code in cshtml
<div class="span4">
<label class="control-label" for="txtCountryId">Country</label>
#Html.DropDownList("Countries", null,
new System.Collections.Generic.Dictionary<string, object> {
{"id", "txtCountryId" },
{ "data-bind","value: CountryId"} })
</div>
this way i got solved the problem

Breezejs flips the EntityState from Added to Modified before Save

I am building a SPA per the guidance provided in John Papa's Jumpstart.
When I create the model, it has
modelObservable().entityAspect.entityState.isAdded() = true;
I update the text, dropdown and
modelObservable().entityAspect.entityState.isAdded() = false;
in my Datacontext:
var createProject = function (position) {
return manager.createEntity(entityNames.project,
{
positionId : position.id(),
start : position.start(),
memberId : position.memberId()
});
};
which is called from my add viewModel:
define(['services/datacontext', 'durandal/plugins/router', 'durandal/system', 'durandal/app', 'services/logger', 'services/uiService'],
function (datacontext, router, system, app, logger, ui) {
var model = ko.observable();
var position = ko.observable();
var hourTypes = ko.observableArray([]);
var isSaving = ko.observable(false);
// init
var activate = function (routeData) {
logger.log('Add View Activated', null, 'add', true);
var positionId = parseInt(routeData.id);
initLookups();
return datacontext.getPositionById(positionId, position).then(**createProject**);
};
var initLookups = function () {
logger.log('initLookups', null, 'add', true);
hourTypes(datacontext.lookups.hourTypes);
};
// state
**var createProject = function () {
return model(datacontext.createProject(position()));
}**
var addNewProject = function () {
if (position == undefined || position().id() < 1) {
console.log('callback addNewProject');
setTimeout(function () {
addNewProject();
}, 1000);
} else {
datacontext.addProject(position(), model);
console.log(model().id());
return;
}
}
var **save** = function () {
isSaving(true);
**datacontext.saveChanges()**
.then(goToEditView).fin(complete);
function complete() {
isSaving(false);
}
function goToEditView() {
isSaving(false);
var url = '#/Projects/';
router.navigateTo(url + model().id());
}
};
var vm = {
activate: activate,
hourTypes: hourTypes,
isAdded: isAdded,
model: model,
save: save,
title: 'Details View'
};
return vm;
});
the html
<section data-bind="with:model">
<h1 data-bind="text: name"> <i class="icon-asterisk" data-bind="visible: hasChanges" style="font-size: 30px;"></i></h1>
<div class="errorPanel"></div>
<div id="overview" class="project" >
<div class="row">
<div class="span4">
<label class="requiredLabel">Name*</label>
<input type="text" name="name" data-bind="value: name" style="width: 27em;" class="required" placeholder="Project Name" required validationMessage="Project Name required" /><span class="k-invalid-msg" data-for="title"></span>
</div>
</div>
<div class="row">
<div class="span3"><label class="requiredLabel">Start*</label></div>
<div class="span3"><label class="requiredLabel">End</label></div>
</div>
<div class="row">
<div class="span3"><input name="start" data-bind="shortDate: start" class="date required" required="required" placeholder="mm/dd/yyyy" style=" width:142px"></div>
<div class="span3"><input name="end" data-bind="shortDate: end" class="date" placeholder="mm/dd/yyyy" style=" width:142px"><span class="k-invalid-msg" data-for="end"></span></div>
</div>
<br/>
<div class="row">
<div class="span3"><label for="hourType" class="requiredLabel">Measure As*</label></div>
<div class="span2"><label for="hoursPerWeek" class="requiredLabel">Hours/Week</label></div>
<div class="span2"><label for="totalHours" class="requiredLabel">Total Hours</label></div>
</div>
<div class="row">
<div class="span3">
<select id="hourType" data-bind="options: $parent.hourTypes, optionsText: 'name', value: hourType" required validationMessage="Measure As required"></select><span class="k-invalid-msg" data-for="hourType"></span>
</div>
<div class="span2">
<input name="hoursPerWeek" type="number" min="1" max="120" required="required" data-bind="value: hoursPerWeek, validationOptions: { errorElementClass: 'input-validation-error' }, enable: hourType().id() == 1" class="hours required"" style="width: 80px;" validationMessage="Hours required"><span class="k-invalid-msg" data-for="projectHours"></span>
<span class="k-invalid-msg" data-for="totalHours"></span>
</div>
<div class="span2">
<input name="totalHours" type="number" min="40" max="2080" required="required" data-bind="value: totalHours, validationOptions: { errorElementClass: 'input-validation-error' }, enable: hourType().id() == 2" class="hours required"" style="width: 80px;" validationMessage="Hours required"><span class="k-invalid-msg" data-for="projectHours"></span>
<span class="k-invalid-msg" data-for="totalHours"></span>
</div>
</div>
<div class="row">
<div class="span4">
<label class="requiredLabel">Description*</label><span class="k-invalid-msg" data-for="description"></span><span id="posMinDesc" style="visibility:hidden"></span>
<textarea id="description" name="description" style="height: 200px; width: 650px;" data-bind="value: description, enabled:true, click: $parent.clearDefaults" rows="4" cols="60" class="richTextEditor k-textbox" required validationMessage="Description required" ></textarea>
</div>
</div>
</div>
<div class="button-bar">
<button class="btn btn-info" data-bind="click: $parent.goBack"><i class="icon-hand-left"></i> Back</button>
<button class="btn btn-info" data-bind="click: $parent.save, enable: $parent.canSave"><i class="icon-save"></i> Save</button>
</div>
</section>
The json breeze sends to my controller is this:
{
"entities": [
{
"Id": -1,
"Description": "poi",
"End": null,
"Gauge": 0,
"Score": 0,
"HourTypeId": 1,
"HoursPerWeek": 45,
"HourlyRate": null,
"TotalHours": null,
"WeightedHours": 0,
"CreditMinutes": 0,
"TotalCompensation": null,
"IsCurrent": false,
"Name": "poi",
"PositionId": 1,
"MemberId": 1,
"Start": "2011-09-01T00:00:00Z",
"undefined": false,
"entityAspect": {
"entityTypeName": "Project:#SkillTraxx.Model",
"defaultResourceName": "Projects",
"entityState": "Modified",
"originalValuesMap": {
"Name": "",
"HourTypeId": 0,
"HoursPerWeek": null,
"Description": ""
},
"autoGeneratedKey": {
"propertyName": "Id",
"autoGeneratedKeyType": "Identity"
}
}
}
],
"saveOptions": {}
}
As you can see, the above is incorrect b/c state is "Modified" and the Id = -1. This throws an error server side. I suppose I could trap the DbUpdateConcurrencyException, unwind the JObject and change "Modified" to added, but that's got code smell all over it.
If anyone can help me find the face-palm moment in all of this, I'm ready.
Thanks for looking!
FACE PALMED IT
I took Jays advice and started stripping away the html then I realize it was my handler.
The update method on shortDate handler was responsible. I wrapped it in an if statement not to send the update if the current state is added.
ko.bindingHandlers.shortDate = {
init: function (element, valueAccessor) {
//attach an event handler to our dom element to handle user input
element.onchange = function () {
var value = valueAccessor();//get our observable
//set our observable to the parsed date from the input
value(moment(element.value).toDate());
};
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
if (valueUnwrapped) {
element.value = moment(valueUnwrapped).format('L');
if (!viewModel.entityAspect.entityState.isAdded())
{
**viewModel.entityAspect.setModified();**
}
}
}
};

Resources