set CSS style using jstl - css

Is there a way to modify css attribute directly using jstl?
Below is what I want to do
<div id="error" align="center">
<img src='resources/warning.png'/>
<c:if test="${not empty error}">
<c:out value='${error}' /> //if i enter here, I want #error 'display' to be 'block'
</c:if>
</div>
So you might say, why not just have the css set to display:block, and put the if tags like this
<c:if test="${not empty error}">
<div id="error" align="center">
<img src='resources/warning.png'/>
<c:out value='${error}' />
</div>
</c:if>
That would be fine, if the only source of my errors were from the controller and passed back in the model. However, I am also making AJAX calls, and say there is a problem browser side, I need to display the error still.
So to do this, for example in my ajax call I do
$.ajax({
url: "url",
beforeSend: function(){
$("body").css("cursor", "wait");
},
dataType:"json",
timeout:15000,
cache: false,
async: false,
success: function(data){
document.getElementById("error").innerHTML="";
document.getElementById("error").style.display = "none";
$("body").css("cursor", "default");
},
error: function(jqXHR, textStatus, errorThrown){
if (textStatus =="timeout"){
document.getElementById("error").innerHTML="Request timed out!";
}
else{
document.getElementById("error").innerHTML= jqXHR.responseText;
}
document.getElementById("error").style.display = "block";
// $("#loading").fadeOut('medium');
$("body").css("cursor", "default");
}
});

<div id="error" align="center" <c:if test="${empty error}">style="display: none;"</c:if>>
<img src='resources/warning.png'/>
<c:if test="${not empty error}">
<c:out value='${error}' />
</c:if>
</div>
or
<div id="error" align="center" style="display: ${(empty error) ? 'none': 'block'};">
<img src='resources/warning.png'/>
<c:if test="${not empty error}">
<c:out value='${error}' />
</c:if>
</div>
should do what you want.

Here's how I did it
<div id="error" align="center">
<img src='resources/critical.png'/>
<span id="errorText">
<c:out value='${error}' />
</span>
</div>
So now the display property is only appying to the containing div 'error'
My jsp is setting text in the 'errorText' field
My ajax javascript is also doing this if it finds an error.
Then, in my javascript, it checks if 'errorText' has anything in it, and sets its display appropriately
$.ajax({
//url: "./test.go?station="+stName+"&date="+rDate,
url: "./getAssignments.go?station="+stName+"&date="+rDate,
beforeSend: function(){
// $("#loading").fadeIn('medium');
$("body").css("cursor", "wait");
},
dataType:"json",
timeout:15000,
cache: false,
async: false,
success: function(data){
document.getElementById("errorText").innerHTML="";
document.getElementById("error").style.display = "none";
pucksJSON=data;
reconstructGates( pucksJSON );
setStationName(stationName);
refresh_time = new Date(); //reset the time counter
// $("#loading").fadeOut('medium');
$("body").css("cursor", "default");
},
error: function(jqXHR, textStatus, errorThrown){
refresh_time = new Date(); //reset the time counter
if (textStatus =="timeout"){
document.getElementById("errorText").innerHTML="Request timed out!";
}
else{
document.getElementById("errorText").innerHTML= jqXHR.responseText;
setStationName(stationName);
reconstructGates( null );
}
document.getElementById("error").style.display = "block";
// $("#loading").fadeOut('medium');
$("body").css("cursor", "default");
}
});
This only works because I set up my controller to return a bad response code if it sets an error. So the Ajax fails and goes to the error section.

Related

Multiple submit button fail to find the handler method in asp.net core 3.1 razor page application

I have a single form which has two button one to upload image using ajax call & other is main submit button which saves all the data.
I am still very new to asp.net core and trying different thing to learn asp.net core with razor page.
I read lot of article about multiple form submit but most of then where using two form with submit button for each.
My issue is when i hit the submit button it fails to find the handler method, after full days troubleshoot nothing worked and last few article point to error/failure to antiforgery, i not sure how to implement it in below code as i tried few but they gave error may be article where old referencing core 2.2 etc example1 example2
I am not sure about the what exactly is causing the issue any help would be appreciate.
I am trying to upload Image using Ajax method in asp.net core Razor pages, I am main form in will all input fields are kept and with the form for Fileupload i am also added addition button which is for file upload using Ajax, When i hit the
<input type="submit" value="Upload Image" asp-page-handler="OnPostUploadImage" id="btnUploadImage" />
i want it to call OnPostUploadImage method in pageModel file but it alway goes to default OnPost method. when i rename the OnPost to OnPost2 nothing happend..
How can i call OnPostUploadImage() on button btnUploadImage click event.
When i hit click btnUploadImage it generates following error on browser console
Error in FF
XML Parsing Error: no root element found Location:
https://localhost:44364/Admin/News/NewsCreate?handler=OnPostUploadImage
Line Number 1, Column 1:
Error in Chrome
jquery.min.js:2 POST
https://localhost:44364/Admin/News/NewsCreateMultipleSubmit?handler=OnPostUpLoadImage
400 (Bad Request)
event though path looks fine but it cant find it as per error message
#page
#model BookListRazor.Pages.Admin.News.NewsCreateModel
#{
ViewData["Title"] = "News Create";
Layout = "~/Pages/Shared/_LayoutAdmin.cshtml";
}
<div class="border container" style="padding:30px;">
<form method="post" enctype="multipart/form-data">
<div class="text-danger" asp-validation-summary="ModelOnly"></div>
<input hidden asp-for="News.NewsImage" />
<input id="fileName" hidden value="" />
<div class="form-group row">
<div class="col-2">
<label asp-for="News.NewsHeading"></label>
</div>
<div class="col-10">
<input asp-for="News.NewsHeading" class="form-control" />
</div>
<span asp-validation-for="News.NewsHeading" class="text-danger"></span>
</div>
<div class="form-group row">
<div class="col-2">
<label asp-for="News.NewsImage"></label>
</div>
<div class="col-10">
#*<input asp-for="News.NewsImage" type="file" class="form-control" id="NewsImage">*#
#*Photo property type is IFormFile, so ASP.NET Core automatically creates a FileUpload control *#
<div class="custom-file">
<input asp-for="NewsImageForUpload" class="custom-file-input form-control">
<label class="custom-file-label">Click here to change photo</label>
<input type="submit" value="Upload Image" asp-page-handler="OnPostUploadImage" id="btnUploadImage" />
</div>
</div>
<span id="imageStatus" class="text-danger"></span>
<span asp-validation-for="NewsImageForUpload" class="text-danger"></span>
</div>
<div class="form-group row">
<div class="col-3 offset-3">
<input id="btnSave" type="submit" value="Create" class="btn btn-primary form-control" />
</div>
<div class="col-3">
<a asp-page="Index" class="btn btn-success form-control">Back to List</a>
</div>
</div>
</form>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="https://cdn.ckeditor.com/4.14.0/full/ckeditor.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
$("#btnSave").addClass("disable-button");
$('.custom-file-input').on("change", function () {
var fileName = $(this).val().split("\\").pop();
$(this).next('.custom-file-label').html(fileName);
$("#fileName").val(fileName);
$("#btnSave").removeClass("disable-button");
});
if ($("#fileName").val() == "") {
//alert("Select Image...");;
}
});
</script>
</div>
#section Scripts{
<partial name="_ValidationScriptsPartial" />
<script>
$(function () {
$('#btnUploadImage').on('click', function (evt) {
console.log("btnUploadImage");
evt.preventDefault();
console.log("btnUploadImage after evt.preventDefault()");
$.ajax({
url: '#Url.Page("", "OnPostUploadImage")',
//data: new FormData(document.forms[0]),
contentType: false,
processData: false,
type: 'post',
success: function () {
alert('Uploaded by jQuery');
}
});
});
});
</script>
}
.cs file CODE
public async Task<IActionResult> OnPost()
{
if (ModelState.IsValid)
{
return Page();
}
else
{
return Page();
}
}
public IActionResult OnPostUploadImage()
{
//Some code here
}
Verify that you add the following code to the ConfigureServices method of startup.cs:
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
If you want to enter the OnPostUploadImage method, the url of the Ajax request needs to be changed to #Url.Page("", "UploadImage") without adding OnPost.
And the Ajax request should send the anti-forgery token in request header to the server.
Change your ajax as follow:
#section Scripts{
<partial name="_ValidationScriptsPartial" />
<script>
$(function () {
$('#btnUploadImage').on('click', function (evt) {
console.log("btnUploadImage");
evt.preventDefault();
console.log("btnUploadImage after evt.preventDefault()");
$.ajax({
url: '#Url.Page("", "UploadImage")',
//data: new FormData(document.forms[0]),
contentType: false,
processData: false,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
type: 'post',
success: function () {
alert('Uploaded by jQuery');
}
});
});
});
</script>
}
You can refer to this for more details.

<form:option value="0"> validation is not working using jquery validation

I am using chosen.js and jquery validation pluging but below code is not working,I am not get any error.please help me how to validate this using jquery validation pluging.
<form:form method="post" id="clienteditform" action="updateClient.htm" name="clienteditform" cssClass="form-horizontal" modelAttribute="eReg" role="form">
<div class="form-group">
<label class="col-sm-2 control-label">Country</label>
<div class="col-sm-10">
<form:select cssClass="chosen-select" cssStyle="width:450px;" id="country" name="country" path="cusDTO.client.cl_country_id">
<form:option value="0">Select country</form:option>
<form:options items="${countryList}" itemValue="country_id" itemLabel="country_name"/>
</form:select>
</div>
</div>
</form>
<script type="text/javascript">
$(document).ready(function(){
$(".chosen-select").chosen();
$.validator.addMethod("validateCountry", function(value, element) {
return this.optional(element) || value != '0' ;
}, " Please select country");
$("#clienteditform").validate({
rules: {
"cusDTO.client.cl_country_id":{
validateCountry : true
}
}
});
});
$(document).ready(function(){
$(".chosen-select").chosen();
$.validator.addMethod("validateCountry", function(value, element) {
return this.optional(element) || value != '0' ;
}, " Please select country");
$("#clienteditform").validate({
rules: {
"cusDTO.client.cl_country_id":{
validateCountry : true
}
}
});
$('#country').rules('add', {validateCountry:true});
});
hope it solve your problem

Add or remove element on knockout validation error or succes

I have a konockout validation:
define([
"jquery",
"knockout",
"knockout.validation",
"inte/accdevice"
], function ($, ko, validation) {
return function (model, getzipcodeurl) {
$(function () {
ko.validation.registerExtenders();
function ViewModelprofile() {
var self = this;
self.firstName = ko.observable(model.FirstName).extend({ required: { message: errors} });
self.updating = ko.observable(true);
};
var vms = new ViewModelprofile();
vms.errors = ko.validation.group(vms);
ko.applyBindingsWithValidation(vms, document.getElementById('infosBlocEdit'), { messagesOnModified: true });
});
};
});
This is my HTML:
<input id="FirstName" name="FirstName" type="text" value="#Model.FirstName" data-bind="value: firstName" maxlength="19" />
<span class="errorMsg" data-bind="validationMessage: firstName"></span>
Actually when there is an error i show:<span class="errorMsg" data-bind="validationMessage: firstName">errors</span>
I need to personalize css on error and on success on each element validation:
On error i need to show this:<span class="invalidLine">
<span class="bble"> </span>
<span class="bbleTxt">errors</span>
</span>
and on succes:<span class="validLine"></span>
How can I do this?
If I understand the question correctly and from what I see you use knockout validation, you need something like:
<span class="invalidLine" data-bind="visible: !firstName.isValid()">
<span class="bble"> </span>
<span class="bbleTxt">errors</span>
</span>
<span class="validLine" data-bind="visible: firstName.isValid()"></span>

Play animation with animate.css when removing item

I am using this CSS file http://daneden.github.io/animate.css/ to add some animation to the web site I am building.
The thing is I need to play an animation when I delete an item from a list for example, but how can I do that since the element is no longer in the DOM?
All right,
here is my jsp code:
<tbody class="filter">
<c:forEach var="message" items="${messages}">
<tr id="${message.id}" class="body">
<td>${message.name}</td>
<c:choose>
<c:when test="${not empty message.file}"><td>${message.file.name}</td></c:when>
<c:otherwise><td>${message.tts}</td></c:otherwise>
</c:choose>
<td class="icon"><i id="delete" class="icon-trash icon-hover"></i></td>
</tr>
</c:forEach>
</tbody>
And some jQuery:
$.ajax({
type: "GET",
url: "message/delete/" + id,
dataType: "json",
success: function(response) {
if (response.status == "OK") {
$row.addClass('animated flipOutX');
// Here I need to run an animation before I delete the item.
$('#messageTable tr#' + id).remove();
}
}
});
Thank you again for your help!
UPDATE:
Demo http://jsfiddle.net/g3WLM/1/

Binding Issues with KnockoutJs and Breeze - Navigation Properties

My app is based on the HotTowel template so it includes Durandal, Knockout & Breeze. I have a page with 3 tables side by side. The first table has a list of "templates', the 2nd table shows "sections" for the selected "template" and the 3rd table shows "items" for the selected "section". The "sections" and "items" tables are collections accessed via navigation properties. I find that I get intermittent binding issues. The data in the "templates" table always shows correctly, however related "sections" and "items" sometimes show correctly and other times one of the other is not populated. It would seem to be a timing issue. My view model and view are below. Am I just going about all of this the wrong way?
define(['services/dataservice', 'services/logger', 'services/model'],
function (ds, logger, model) {
var templates = ko.observableArray();
var selectedTemplate = ko.observable();
var selectedSection = ko.observable();
var selectedItem = ko.observable();
var newTemplateTitle = ko.observable();
var newSectionTitle = ko.observable();
var newItemTitle = ko.observable();
function activate() {
newTemplateTitle('');
newSectionTitle('');
newItemTitle('');
logger.log('Templates view activated', null, 'templates', false);
return ds.getTemplatePartials(templates, false, false);//.then(succeeded);
//function succeeded() {
// var firstTemplate = templates()[0];
// setSelectedTemplate(firstTemplate);
//}
}
templates.subscribe(function() {
var firstTemplate = templates()[0];
setSelectedTemplate(firstTemplate);
});
var deactivate = function () {
templates([]);
};
function refresh() {
return ds.getTemplatePartials(templates, true, false);
}
var viewAttached = function (view) {
bindEventToList(view, '#template-list', setSelectedTemplate);
bindEventToList(view, '#section-list', setSelectedSection);
bindEventToList(view, '#item-list', setSelectedItem);
return true;
};
var addTemplate = function () {
var newTemplate = ds.createEntity(model.entityNames.document);
newTemplate.title(newTemplateTitle());
newTemplate.isTemplate(true);
newTemplate.organisation(ds.getCurrentOrganisation()());
return ds.saveChanges().then(saveSucceeded);
function saveSucceeded() {
templates.push(newTemplate);
templates.sort();
newTemplateTitle('');
}
};
var addSection = function () {
var newSection = ds.createEntity(model.entityNames.section);
newSection.title(newSectionTitle());
newSection.isTemplate(true);
newSection.document(selectedTemplate());
return ds.saveChanges().then(saveSucceeded);
function saveSucceeded() {
newSectionTitle('');
}
};
var addItem = function () {
var newItem = ds.createEntity(model.entityNames.item);
newItem.title(newItemTitle());
newItem.isTemplate(true);
newItem.section(selectedSection());
return ds.saveChanges().then(saveSucceeded);
function saveSucceeded() {
newItemTitle('');
}
};
var isTemplateSelected = function (template) {
if (template && selectedTemplate()) {
var thisId = ko.utils.unwrapObservable(selectedTemplate().id);
return ko.utils.unwrapObservable(template.id) == thisId;
}
return false;
};
var isSectionSelected = function (section) {
if (section && selectedSection()) {
var thisId = ko.utils.unwrapObservable(selectedSection().id);
return ko.utils.unwrapObservable(section.id) == thisId;
}
return false;
};
var isItemSelected = function(item) {
if (item && selectedItem()) {
var thisId = ko.utils.unwrapObservable(selectedItem().id);
return ko.utils.unwrapObservable(item.id) == thisId;
}
return false;
};
var vm = {
activate: activate,
deactivate: deactivate,
templates: templates,
//sections: sections,
//items: items,
selectedTemplate: selectedTemplate,
selectedSection: selectedSection,
selectedItem: selectedItem,
title: 'Template Maintenance',
refresh: refresh,
viewAttached: viewAttached,
addTemplate: addTemplate,
addSection: addSection,
addItem: addItem,
newTemplateTitle: newTemplateTitle,
newSectionTitle: newSectionTitle,
newItemTitle: newItemTitle,
isTemplateSelected: isTemplateSelected,
isSectionSelected: isSectionSelected,
isItemSelected: isItemSelected
};
return vm;
//#region internal methods
function setSelectedTemplate(data) {
if (data) {
selectedTemplate(data);
return selectedTemplate().entityAspect.loadNavigationProperty("sections").then(setFirstSectionSelected);
} else {
return false;
}
function setFirstSectionSelected() {
setSelectedSection(selectedTemplate().sections()[0]);
}
}
function setSelectedSection(data) {
if (data) {
selectedSection(data);
return selectedSection().entityAspect.loadNavigationProperty("items").then(setFirstItemSelected);
} else {
selectedSection();
selectedItem();
return false;
}
function setFirstItemSelected() {
setSelectedItem(selectedSection().items()[0]);
}
}
function setSelectedItem(data) {
if (data) {
selectedItem(data);
} else {
selectedItem();
}
}
function bindEventToList(rootSelector, selector, callback, eventName) {
var eName = eventName || 'click';
$(rootSelector).on(eName, selector, function () {
var item = ko.dataFor(this);
callback(item);
return false;
});
}
//#region
}
);
<section>
<div class="row-fluid">
<header class="span12">
<button class="btn btn-info pull-right push-down10" data-bind="click: refresh">
<i class="icon-refresh"></i> Refresh</button>
<h4 class="page-header" data-bind="text: title"></h4>
</header>
</div>
<div class="row-fluid">
<section class="span3">
<header class="input-append">
<input id="newTemplateName"
type="text"
data-bind="realTimeValue: newTemplateTitle"
placeholder="New template name"
class="input-medium" />
<button class="btn btn-info add-on" data-bind="click: addTemplate, disable: newTemplateTitle() === ''">
<i class="icon-plus"></i> Add</button>
</header>
<article>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Templates</th>
</tr>
</thead>
<tbody>
<!-- ko foreach: templates -->
<tr id="template-list" data-bind="css: { 'selected': $root.isTemplateSelected($data) }">
<td data-bind="text: title" />
</tr>
<!-- /ko -->
</tbody>
</table>
<span>Count: <span data-bind="text: templates().length"></span></span>
</article>
</section>
<section class="span5">
<header class="input-append">
<input id="newSectionName"
type="text"
data-bind="realTimeValue: newSectionTitle"
placeholder="New section name"
class="input-medium" />
<button class="btn btn-info add-on" data-bind="click: addSection, disable: newSectionTitle() === ''">
<i class="icon-plus"></i> Add</button>
</header>
<article data-bind="if: selectedTemplate">
<table class="table table-striped table-bordered table-hover" >
<thead>
<tr>
<th data-bind="text: 'Sections for ' + selectedTemplate().title()"></th>
</tr>
</thead>
<tbody>
<!-- ko foreach: selectedTemplate().sections() -->
<tr id="section-list" data-bind="css: { 'selected': $root.isSectionSelected($data) }">
<td data-bind="text: title" />
</tr>
<!-- /ko -->
</tbody>
</table>
<span>Count: <span data-bind="text: selectedTemplate().sections().length"></span></span>
</article>
</section>
<section class="span4">
<header class="input-append">
<input id="newItemName"
type="text"
data-bind="realTimeValue: newItemTitle"
placeholder="New item name"
class="input-medium" />
<button class="btn btn-info add-on" data-bind="click: addItem, disable: newItemTitle() === ''">
<i class="icon-plus"></i> Add</button>
</header>
<article data-bind="if: selectedSection">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th data-bind="text: 'Items for ' + selectedSection().title()"></th>
</tr>
</thead>
<tbody>
<!-- ko foreach: selectedSection().items() -->
<tr id="item-list" data-bind="css: { 'selected': $root.isItemSelected($data) }">
<td data-bind="text: title" />
</tr>
<!-- /ko -->
</tbody>
</table>
<span>Count: <span data-bind="text: selectedSection().items().length"></span></span>
</article>
</section>
</div>
Similar issue (same server, same client but sometimes some navigators not working in breeze) happened to me. In my opinion it can be a timing bug. Or the create/load order of entities count.
I've changed this paralell async load entities from server:
return promise = Q.all([
getPackage(),
getClubPartials(null, true),
getAddressPartials(null, true),
getEventPartials(null, true)
]).then(success);
to this get them one by one:
return getClubPartials(null, true).then(function () {
getAddressPartials(null, true).then(function () {
getEventPartials(null, true).then(function () {
return getPackage().then(success);
})
})
});
And my problem gone!
There is just a lot of code to wade through and try to make sense of in the imagination.
You seem to say it works some of the time. That does sound like a timing issue.
One thing that is disturbing is the async methods (e.g. setSelectedTemplate) that return either false or a promise; not sure why the inconsistency. But that is probably not the real problem.
You could try putting a setTimeout(..., 10) before exiting the async methods. See if that changes the behavior.
If that doesn't reveal it, you'll have to boil it down to just those the essentials that reveal the problem.
Sadly no sudden flash of insight today.
Update June 3
My first concern is that some of your methods return promises and some return the value false. I'd feel more comfortable if they all returned promises. Look at Q.resolve().
Other code baffles me. For example, what is going on in the many variations on this pattern:
function setSelectedItem(data) {
if (data) {
selectedItem(data);
} else {
selectedItem();
}
}
The else{...} isn't doing anything useful. It unwraps the selectedItem property ... and discards the value. What is the point?
And what is the difference between this:
thisId = ko.utils.unwrapObservable(selectedTemplate().id); // obscure
and this?
thisId = selectedTemplate().id(); // clear
Are you unsure whether selectedTemplate().id is a KO observable? The only reason to use unwrapObservable is when you are unsure.
As for timing, you can let KO know that it should re-fresh a binding by calling valueHasMutated() on an observable. For example:
function setFirstItemSelected() {
setSelectedItem(selectedSection().items()[0]);
selectedItem.valueHasMutated();
}
It might help. I don't know ... you're stacking a long chain of dependencies and it isn't easy to see which are bailing out when. That would take study of actual data flows as well as the code. You cannot reasonably expect your StackOverflow audience to work that hard for free.
Try cutting this way down to a super-simple example that displays the troublesome behavior.
Best of luck.

Resources