Compare 2 Date Picker Values During Registration - c#

I have extended the default registration form in ASP.NET MVC with 2 jquery-ui datepickers.
<div class="form-group">
#Html.LabelFor(m => m.LicenseDateOfIssuance, "Date of Issue", new { #class = "col-md-3 control-label required-field" })
<div class="col-md-9">
#Html.EditorFor(m => m.LicenseDateOfIssuance, new { htmlAttributes = new { #class = "form-control DateTimePicker", placeholder = "Date of Issuance", #readonly = "true" } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.LicenseDateOfExpiry, "Date of Expiry", new { #class = "col-md-3 control-label required-field", placeholder = "eg 1 Jan 2015" })
<div class="col-md-9">
#Html.EditorFor(m => m.LicenseDateOfExpiry, new { htmlAttributes = new { #class = "form-control DateTimePicker", placeholder = "Date of Expiry", #readonly = "true" } })
</div>
</div>
I would like to compare the dates held by both datepickers and ensure that the expiry div's date is later than the issuance div.
Any suggestions would be very much appreciated.

Hi you can use foolproof mvc extensions: http://foolproof.codeplex.com
or you may also use MVC remote validation that is my personal favorite. Here is an example:
MVC 5 Remote Validation

I prefer to use MVC validation but if you want only client side then try this script. It does format date as day/month/year.
$(document).ready(function() {
var options = {
dateFormat: "dd/mm/yy"
};
$("#LicenseDateOfIssuance").datepicker(options);
$("#LicenseDateOfExpiry").datepicker(options);
$("#validate").click(function() {
var from = GetDate($("#LicenseDateOfIssuance").val());
var to = GetDate($("#LicenseDateOfExpiry").val());
if (from > to) {
alert("Invalid Date Range");
} else {
alert('ok');
};
});
});
function GetDate(date) {
var parts = date.split('/');
return new Date(parts[2], parts[1], parts[0]);
};
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<p>License of issuance: <input type="text" id="LicenseDateOfIssuance"></p>
<p>License of expiry: <input type="text" id="LicenseDateOfExpiry"></p>
<button id="validate">Validate range</button>

Related

Enable past days on datetime picker

I'm solving a little bug of an application but I have difficulty on a DateTimePicker. In a View of the application I added a DateTimePicker that needs to allow the user to select values in the past. Strangely the object disable the old dates. How can i solve it?
I tried to use DateTimePicker from other pages that actually works as the one i need to implement. But it doesn't work.
That's the code of the page where I'm trying to implement the DateTimePicker.
#{
ViewBag.Title = "CambioTarga";
ViewBag.provenienza = "CambioTarga";
TempData["FromCambioTarga"] = true;
}
<div class="form1">
#Html.Partial("~/Views/Condivise/_Anagrafica.cshtml", (RSM.BusTuristiciBO.SourceDataReference.AnagraficaCliente)ViewBag.anagrafica)
#Html.Partial("~/Views/Condivise/_DatiSocietari.cshtml", (RSM.BusTuristiciBO.SourceDataReference.Dati_Soggetti)ViewBag.dati)
#Html.Partial("~/Views/Condivise/_DettaglioPermesso.cshtml", Model)
#Html.Partial("~/Views/Condivise/_VisuraTargaRidotta.cshtml", (RSM.BusTuristiciBO.SourceDataReference.DatiVisura)ViewBag.datiVisura)
<h4 class="colorH4">Elenco Documenti Allegati Alla Richiesta </h4>
#Html.Partial("~/Views/RichiesteWeb/Dettagli/Trasversali/_ElencoDocumenti.cshtml", (IEnumerable<RSM.BusTuristiciBO.SourceDataReference.Documento>)ViewBag.allegati)
#if (Model.Stato == "PagamentoInValutazione")
{
<div class="row">
<div class="col-sm-4">
#Html.Label("", "Data iniziale", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.DataInserimento, new { htmlAttributes = new { #class = "form-control datetimepicker", #Value = Model.DataInserimento.ToShortDateString(), required = "required" }, #language = "it", type = "text" })<br />
#Html.ValidationMessageFor(model => model.DataInserimento, "", new { #class = "text-danger" })
</div>
</div>
}
#Html.Partial("~/Views/BTAbbonamenti/_Tariffa.cshtml", (RSM.BusTuristiciBO.SourceDataReference.Tariffa)ViewBag.Tariffa)
<br />
<!-- partial bottoni-->
#Html.Partial("~/Views/RichiesteWeb/Dettagli/Trasversali/_RichiesteButtons.cshtml", Model)
#*#if (Model.Stato != "PagamentoInValutazione")
{
<script>
$('#divPagaRata').hide();
</script>
}
else
{
<script>
$('#btnAccetta').hide();
</script>
}*#
#if (Model.Stato == "InAttesaDiPagamento")
{
<script>
$('#btnAccetta').hide();
</script>
}
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#pnlCambioTarga").hide();
$('#ddlTipoPagamento').val('7');
$("#txtImporto").prop('disabled', true);
$("#ddlTipoPagamento").prop('disabled', true);
$('#btn_VisuraIndietro').hide();
})
</script>```

Client-side validation of US currency

I have an ASP.Net MVC 5 web application and I need to accept user input of US currency. Some valid inputs might be:
100
$100.21
$ 1,234
$1,234.56
Invalid inputs might be:
10,12
1o0.21
My (simplified) model looks like:
public class Claim {
[DisplayName("$ Amount)]
[DataType(DataType.Currency)]
[Required]
[Range(0.0, 200000.0)]
public decimal? DollarAmount { get; set; }
}
My cshtml markup looks like:
#Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9">
#Html.EditorFor(model => model.DollarAmount, new { htmlAttributes = new { #class = "form-control margin-bottom" } })
#Html.ValidationMessageFor(model => model.DollarAmount, "", new { #class = "text-danger" })
</div>
I used this advice this advice to build a binder that converts user input to a decimal, but client-side validation won't let the user enter a dollar-sign or commas. What do I need to do to allow the user to enter valid currency values, but warns her if she enters an invalid value? I'd prefer to do as much validation on the client-side as possible.
You Might want to look at https://github.com/globalizejs/globalize#currency-module. Helps allot with this kind of stuff. As for your Question to be able to use the Dollar Symbol you would not be able to store this Value as a decimal format in the database, only as a string.
There are a few things you can do, Use bootstrap to place a Dollar symbol in front of your TextBox using input-group-addon. Not sure if it will work properly as i see you have set Margin-bottom on your Textbox, telling me you might not be using bootstrap form tags above.
You may want to look into AutoNumeric jQuery plugin, It's well-maintained and they've basically "thought of everything" I could want for currency.
// View
#Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9 input-group">
<span class="input-group-addon">$</span>
#Html.EditorFor(model => model.DollarAmount, new { htmlAttributes = new { #class = "form-control margin-bottom" } })
#Html.ValidationMessageFor(model => model.DollarAmount, "", new { #class = "text-danger" })
</div>
// Class
public class Claim {
[DisplayName("$ Amount")]
[DataType(DataType.Currency)]
// {0:C} Will show as currency {0:N} to show Numbers
[DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true))]
[Required]
[Range(0.0, 200000.0)]
public decimal? DollarAmount { get; set; }
}
Another option is to have a hidden field with javascript that will duplicate the field from a string to decimal and that can be the one you submit like below.
// MODEL
public class Claim {
[DisplayName("$ Amount")]
[DataType(DataType.Currency)]
[Required]
[Range(0.0, 200000.0)]
public decimal? DollarAmount { get; set; }
}
// View
#Html.HiddenFor(model => model.DollarAmount, new { #id = "DollarAmount" })
#Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9 input-group">
<span class="input-group-addon">$</span>
<input id="DollarSave" type="text" name="DollarSave" pattern="^\$?([0-9]{1,3},([0-9]{3},)*[0-9]{3}|[0-9]+)(.[0-9][0-9])?$" title="You must enter in proper currency">
#Html.ValidationMessageFor(model => model.DollarAmount, "", new { #class = "text-danger" })
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
$('#DollarSave').change(function(){
var sourceField = $("#DollarSave").val(); //source field key
$("#DollarAmount").val(sourceField); //destination field key
$("#DollarAmount").change(); //destination field key
});
});
</script>
Pool pro's answer was a great help in solving my problem but I couldn't get his input tag pattern to display a message. It worked in JSFiddles, but not in my Asp.Net view template. So, I did the pattern validation and message update in javascript. I also used a different regex. For completeness, I'm posting my solution here:
#Html.HiddenFor(model => model.DollarAmount, new { #id = "DollarAmount" })
#Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9">
<input id="DollarSave" type="text" name="DollarSave" class="form-control text-box single-line">
<p id="BadDollarSave" class="text-danger"></p>
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
$('#DollarSave').on('blur', function () {
validateDollarSave();
});
function validateMoney(inputId) {
var errorMsg = '';
var currency = $('#DollarSave').val();
var good = currency.match(/^(\$|\$ )?[0-9]{1,3}(?:(,[0-9]{3})*|([0-9]{3})*)(?:(\.|\.[0-9]{2}))?$/);
if (!good) {
errorMsg = "$ Amount must be US currency";
} else {
var num = currency.replace(/[, $]/g, "");
$('#DollarAmount').val(num);
}
document.getElementById('BadDollarSave').innerHTML = errorMsg;
};
});
</script>

Render ASP.NET MVC PartialView Using AngularJS

I am trying to integrate Report Viewer for MVC to my angular app with ASP.NET MVC 5.
REPORT:
View/Report/Index.cshtml
#model JET.Shop.Common.Models.ReportRequestModel
#using ReportViewerForMvc;
<div>
<div class="row">
<div class="col-md-5">
#using (Html.BeginForm("Index", "Report", FormMethod.Post))
{
<div class="form-group">
<label>Start Date</label>
#Html.TextBoxFor(model => model.StartDate, string.Format("{0:d}", DateTime.Now), new { #id = "startDate", #class = "datefield", type = "date" })
</div>
<div class="form-group">
<label>End Date</label>
#Html.TextBoxFor(model => model.EndDate, string.Format("{0:d}", DateTime.Now), new { #id = "endDate", #class = "datefield", type = "date" })
</div>
}
</div>
<div class="col-md-7">
<div class="form-group">
<input type="submit" value="Generate" />
</div>
</div>
</div>
<div class="row">
#Html.ReportViewer(ViewBag.ReportViewer as Microsoft.Reporting.WebForms.ReportViewer)
</div>
</div>
ReportController
public class ReportController : Controller
{
// GET: Report
public ActionResult Index(ReportType reportType = ReportType.SalesOrderList)
{
ReportRequestModel model = new ReportRequestModel();
model.Type = reportType;
model.StartDate = DateTime.Now;
model.EndDate = DateTime.Now;
return PartialView(model);
}
[HttpPost]
public ActionResult Index(ReportRequestModel request)
{
List<ReportParameter> reportParams = new List<ReportParameter>();
ReportViewer reportViewer = new ReportViewer();
reportViewer.ProcessingMode = ProcessingMode.Local;
SalesOrdersListDataSet salesOrderDataSet = new SalesOrdersListDataSet();
salesOrderDataSet.SalesOrder.AddSalesOrderRow(Guid.NewGuid(), DateTime.Now, DateTime.Now, DateTime.Now.AddDays(1), 500, 60, 440, "Complete");
salesOrderDataSet.SalesOrder.AddSalesOrderRow(Guid.NewGuid(), DateTime.Now, DateTime.Now, DateTime.Now.AddDays(1), 100, 12, 88, "Complete");
ReportDataSource reportDataSource1 = new ReportDataSource();
reportDataSource1.Name = "Report"; //Name of the report dataset in our .RDLC file
reportDataSource1.Value = salesOrderDataSet.SalesOrder;
reportViewer.LocalReport.DataSources.Add(reportDataSource1);
reportViewer.LocalReport.ReportEmbeddedResource = "JET.Shop.WebApp.Reports.SalesOrderListReport.rdlc";
reportViewer.LocalReport.SetParameters(reportParams);
ViewBag.ReportViewer = reportViewer;
return PartialView(request);
}
}
RouteConfig
routes.MapRoute(
name: "ReportController",
url: "Report/Index/{reportType}",
defaults: new { controller = "Report", action = "Index", reportType = UrlParameter.Optional }
);
$RouteProvider
.when("/Report", {
templateUrl: "/Report/Index",
controller: "ReportController",
loginRequired: true,
requiredRoles: ["Admin"]
})
I basically wanna try to render this report viewer but I got stuck with getting HTTP 500 - Internal Server Error on the console.
I did some random trial and error and found out that if I make my Report/Index.cshtml contain nothing but plain HTML (no razor) it renders. But when I include my #model statement on the view I get HTTP 500. Can anyone help me with this issue? Breakpoints to my controller (GET Index) works fine.
FYI I navigate to the Report page by accessing it directly via URL on the browser for quick testing only.
Any suggestions on how should I approach this? My main goal is to display a ReportViewer because I can work from there once it gets rendered on the view.
Report/Index.cshtml with plain HTML that works..
#*#model JET.Shop.Common.Models.ReportRequestModel
#using ReportViewerForMvc;*#
<div>
<div class="row">
<div class="col-md-5">
#*#using (Html.BeginForm("Index", "Report", FormMethod.Post))
{
<div class="form-group">
<label>Start Date</label>
#Html.TextBoxFor(model => model.StartDate, string.Format("{0:d}", DateTime.Now), new { #id = "startDate", #class = "datefield", type = "date" })
</div>
<div class="form-group">
<label>End Date</label>
#Html.TextBoxFor(model => model.EndDate, string.Format("{0:d}", DateTime.Now), new { #id = "endDate", #class = "datefield", type = "date" })
</div>
}*#
THIS WORKS FINE!
</div>
<div class="col-md-7">
<div class="form-group">
<input type="submit" value="Generate" />
</div>
</div>
</div>
<div class="row">
#*#Html.ReportViewer(ViewBag.ReportViewer as Microsoft.Reporting.WebForms.ReportViewer)*#
</div>
</div>
Just to close this question,
I ended up not using the report viewer at all. I just created an MVC controller that generates an Excel/PDF from a crystal report.

TextBoxFor value not passed to model when disabled

I have a disabled input-field displaying data from a model.
<div class="form-group">
#Html.LabelFor(model => model.first_name, "Förnamn", new
{
#for = "inputFirstname",
#class = "col-lg-3 control-label"
})
<div class="col-lg-9">
#Html.TextBoxFor(model => model.first_name, new
{
#type = "text",
#class = "form-control",
#id = "inputFirstname",
text = Html.DisplayNameFor(model => model.first_name),
disabled="disabled"
})
</div>
</div>
I can submit this data to a controlelr method:
[HttpPost]
public ActionResult Index(RegistrationModel RegistrationModelViewModel)
{}
When i add disabled="disabled" the first_name data is null, if i remove it i get the correct data.
What am i doing wrong?
You may want to use readonly property, if you want to also display the data:
#Html.TextBoxFor(model => model.first_name, new
{
#readonly = "readonly"
})
You need to add an <input type="hidden" name="whateverName" /> on the page which matches the disabled field. By default, it will not be sent to the server.

Uncaught Error: Unable to parse bindings; Message: ReferenceError: xxx is not defined;

This is my first use of Knockout.js.
I don't understand why I have this problem.
Uncaught Error: Unable to parse bindings.
Message: ReferenceError: DataPrevista is not defined;
Bindings value: value:DataPrevista, namePath: true
I wish anyone help me.
This is my code:
View
<div>
#Html.LabelFor(model => model.Cliente)
</div>
<div>
#Html.DropDownListFor(model => model.Cliente.Codigo, new SelectList(Model.ClientesSelecionaveis, "Value", "Text", Model.Cliente), new { #class = "form-control" })
</div>
<div>
#Html.LabelFor(model => model.Funcionario)
</div>
<div>
#Html.DropDownListFor(model => model.Funcionario.Codigo, new SelectList(Model.FuncionariosSelecionaveis, "Value", "Text", Model.Cliente), new { #class = "form-control" })
</div>
<fieldset>
<div style="margin:30px 0;">
<input type="button" value="Adicionar Agendamento" data-bind="click: addAgendamento" class="btn btn-success" />
<input type="button" value="Remover Agendamento" data-bind="click: removeAgendamento" class="btn btn-danger" />
</div>
<h4 class="page-header">Agendamentos</h4>
#Html.EditorFor(model => model.Agendamentos)
</fieldset>
<p style="margin:30px 0;">
<input type="submit" value="Enviar" class="btn btn-info" />
#Html.ActionLink("Listar", "Index")
</p>
Editor Template
<div>
#Html.LabelFor(model => model.DataPrevista)
</div>
<div>
#Html.TextBoxFor(model => model.DataPrevista, new { #class = "form-control", data_bind = "value: dataPrevista, namePath: true" })
</div>
<div>
#Html.LabelFor(model => model.InicioPrevisto)
</div>
<div>
#Html.TextBoxFor(model => model.InicioPrevisto, new { #class = "form-control", data_bind = "value: inicioPrevisto, namePath: true" })
</div>
<div>
#Html.LabelFor(model => model.FimPrevisto)
</div>
<div>
#Html.TextBoxFor(model => model.FimPrevisto, new { #class = "form-control", data_bind = "value: fimPrevisto, namePath: true" })
</div>
<div>
#Html.LabelFor(model => model.TrasladoPrevisto)
</div>
<div>
# Html.TextBoxFor(model => model.TrasladoPrevisto, new { #class = "form-control", data_bind = "value: trasladoPrevisto, namePath: true" })
Javascript
<script type="text/javascript" language="javascript">
function createViewModel() {
var createAgendamento = function () {
return {
dataPrevista: ko.observable(),
inicioPrevisto: ko.observable(),
fimPrevisto: ko.observable(),
trasladoPrevisto: ko.observable()
};
};
var addAgendamento = function () {
agendamentos.push(createAgendamento());
};
var removeAgendamento = function () {
agendamentos.pop();
};
var cliente = ko.observable();
var funcionario = ko.observable();
var agendamentos = ko.observableArray([createAgendamento()]);
return {
cliente: cliente,
funcionario: funcionario,
agendamentos: agendamentos,
addAgendamento: addAgendamento,
removeAgendamento: removeAgendamento
};
}
$(document).ready(function () {
var viewModel = createViewModel();
ko.applyBindings(viewModel);
});
It appears your data syntax is incorrect. It should be data-bind not data_bind
See Knockout documentation: binding syntax
Also dataPrevista is a nested observable within your view model, so you would need to reference it like this.
data-bind="value: agendamentos.dataPrevista"

Categories