Inconsistent error message DOM betweeen jQuery validation and Postback - c#

My error message html structure from jQuery validation and from postbacks are different causing my validation errors to display differently. I need the nested span tag within the span.field-validation-error because I use CSS to add the (x) icon before the message like the one you see on the Description error message.
This is the error message from jQuery validation.
<span class="field-validation-error" data-valmsg-for="Code" data-valmsg-replace="true">
<span id="Code-error" class="">The Description field is required.</span>
</span>
notice that on the banner url validation message, there's no span tag within the span.field-validation-error.
<span class="field-validation-error" data-valmsg-for="BannerUrl" data-valmsg-replace="true">
The Banner Image field is required.
</span>
This is the view cshtml file markup I have.
<div class="form-group">
#Html.LabelFor(x => x.Description):
#Html.TextAreaFor(x => x.Description, new { rows = 5, cols = 5, #class = "form-control", placeholder = "Enter your team description" })
#Html.ValidationMessageFor(x => x.Description)
</div>
<div class="form-group">
#Html.LabelFor(x => x.BannerUrl):
<input id="BannerUrl" name="BannerUrl" type="file" class="file-styled">
#Html.ValidationMessageFor(x => x.BannerUrl)
</div>
Why does the error message html from jquery validation different from the error message html that's generated after postback?
EDIT:
Below is the CSS that adds the (X) icon before the error message. What I really want it to do is for the icon to show up in front of the error message that comes from a postback (no nested span) and also the error message from jquery validation (nested span).
.field-validation-error > span:before {
font-family: 'icomoon';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
min-width: 1em;
display: inline-block;
text-align: center;
font-size: 16px;
vertical-align: middle;
position: relative;
top: -1px;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\ed63";
margin-right: 5px;
}

The jquery.validate.js plugin and the MVC framework are developed by separate teams (jquery.validate is not associated with Microsoft). The MVC framework just uses jquery.validate.js for client side validation (and use jquery.validate.unobtrusive.js to add the rules to jquery.validate.js).
You could create you own HtmlHelper extension to generate the inner <span> element server side. For example, copy the ValidationExtensions.cs source code and modify the private static MvcHtmlString ValidationMessageHelper(...) method so that instead of builder.SetInnerText(validationMessage); you use builder.InnerHtml = xx; where xx is a TagBuilder that builds a <span> containing the error message.
However, it would be easier to just use some javascript to wrap the inner text inside a <span> element when the page is first loaded
// Get all the elements generated by ValidationMessageFor() that have an error
var errors = $('.field-validation-error');
$.each(errors, function (index, item) {
// Wrap the text in a span element
$(this).wrapInner('<span></span>');
})
Note that the jquery.validate plugin also adds an id attribute to the span based on the property name. It does not appear that you need that based on your css, however, if you do want to include that, then you can use
$.each(errors, function (index, item) {
var id = $(this).data('valmsg-for').replace(/[\.\[\]]/g, "_") + '-error';
var span = $('<span></span>').attr('id', id);
$(this).wrapInner(span);
})
Another option would be to wrap each ValidationMessageFor() inside an element, for example
<span class="error">
#Html.ValidationMessageFor(...)
</span>
and modify the css selector
.error > .field-validation-error:before {
font-family: 'icomoon';
....
}

Related

How Send text to textarea in webbrowser C#

This is the textarea. I want to send value there but. There isnt name or id. I couldnt send value.
<div id="cke_1_contents" class="cke_contents cke_reset" role="presentation" style="height: 300px;">
<textarea style="width: 100%; height: 100%; resize: none; outline: currentcolor none medium; text-align: left; -moz-tab-size: 4;" dir="ltr" class="cke_source cke_reset cke_enable_context_menu cke_editable cke_editable_themed cke_contents_rtl" tabindex="0" role="textbox" aria-multiline="true" aria-label="ویرایش‌گر متن غنی, txtPostContent" title="ویرایش‌گر متن غنی, txtPostContent"></textarea>
</div>
you can set the value of textarea inside the WebBrowser component by executing the below code
//get the main div HTML element by ID
var cke1ContentsElements = webBrowser1.Document.GetElementById("cke_1_contents");
//from main div select all HTML elements with the tag name "textarea"
var cke1TextareaList = cke1ContentsElements.GetElementsByTagName("textarea");
//from the selected list of items set value attribute for first element
cke1TextareaList[0].SetAttribute("value", "Send This String To TextArea ");

How to disable the buttons of other URL opening using Iframe?

I m using iframe to open another webservice. there user can view the complete the nav of the targeted link. but i wan't to prevent the user to view the complete nav.
There are five items in the targetd URL like this:
Overview
Call Log
Terrif
Payment
Logout
<iframe id="subframe" frameborder="0" scrolling="no" src="login.aspx" style="float: left;height: 754px; margin-left: 118px; width: 727px;" ></iframe>
Now what i want is that, allow user only to view the Call Log.
How could be this possible to do?
Which steps could be taken to perform these all?
If the service is on your own domain, you can access the frames DOM like so:
var myFrame = frames["myFrame"]
var cssLink = document.createElement("link")
cssLink.href = "iframeStyles.css"; /* change this to the url for a stylesheet targetting the iframe */
cssLink .rel = "stylesheet";
cssLink .type = "text/css";
frames['myFrame'].document.body.appendChild(cssLink);
Also see this question:
How to add CSS class and control elements inside of the Iframe using javaScript.?
If the iframe loads a page from another domain, you may not alter it, because that would be against the same origin policy.
I used this a couple of months before.. Some edits might be required:
<div id="IframeWrapper">
<div id="iframeBlocker">
</div>
<iframe id="mainframe" src="http://www.xyz.com/"></iframe>
</div>
CSS:-
#IframeWrapper
{
position: relative;
}
#iframeBlocker
{
position: absolute;
top: 0;
left: 0;
width: 700px;
height: 450px;
}
#mainframe
{
overflow: hidden;
border-width: 0px;
}
OTHER ALTERNATE AND A BETTER ONE

Adding Parameters to URL.Action in Razor

Hi all Currently I have a website that has a button and some javascript that creates a loading look and then runs this actionresult. I want to add parameters to actionresult but not sure how to do it. Thanks! Here is my code
Controller:
[HttpPost]
public ActionResult PostMethod(string MyText)
{
System.Threading.Thread.Sleep(5000);
return Json("And were done");
}
View:
<input type="text" name="MyTextBlock"/>
<p id="PID">
Default message from declarative syntax.
</p>
<div id="divLoading" style="margin: 0px; padding: 0px; position: fixed; right: 0px;
top: 0px; width: 100%; height: 100%; background-color: #666666; z-index: 30001;
opacity: .8; filter: alpha(opacity=70);display:none" >
<p style="position: absolute; top: 30%; left: 45%; color: White;" align="center">
<img src="../../Content/themes/base/images/ajax-loading.gif"><br />
Loading, please wait...
</p>
</div>
<button onclick="JavascriptFunction();">HTTPPost Button</button>
<script type="text/javascript" language="javascript">
function JavascriptFunction() {
var url = '#Url.Action("PostMethod", "MyTextBlock", new { MyText = "john" })';
$("#divLoading").show();
$.post(url, null,
function (data) {
$("#PID")[0].innerHTML = data;
$("#divLoading").hide();
});
}
</script>
What I want to do is pass MyTextBox into PostMethod to use it as MyText. Some of the other examples I have seen hardcode in values where I want it to be from the textbox. Any help is greatly appreciated. Thanks!
Razor is generated before page load, so if you want a textbox after the page is loaded you need to use javascript (that is to say if the end-user will be changing the value of MyTextBox and you want to pass this new value using AJAX).
Instead of passing null as your data argument in $.post, this is where you would grab the value of MyTextBox and pass it to the action. For example:
var url = '#Url.Action("PostMethod")';
var data = $('input[name="MyTextBox"]').serialize();
$.post(url, data, function(data){
});
It seems like you're trying to hand code a lot of what MVC already handles for you. Try this out...
First out, create a model for your view. You can call this whatever you want. Put the properties that you want as your parameters to your action method in here.
YourModel.cs
public class YourModel
{
public string MyText { get;set; }
}
For your controller, you'll have to change two things. The GET action for the page will need a model passed to it, like shown below.
For the POST action, change your string MyText parameter to YourModel model. This will allow MVC to bind your inputs on your view to the model.
Action Method
public class YourController
{
[HttpGet]
public ActionResult PostMethod()
{
YourModel model = new YourModel();
return View(model);
}
[HttpPost]
public ActionResult PostMethod(YourModel model)
{
//Do something with model.MyText;
System.Threading.Thread.Sleep(5000);
return Json("And We're Done");
}
}
PostMethod.cshtml
//THIS LINE HERE IS THE MOST IMPORTANT
#model YourNamespace.YourModel
//Ajax will handle most of the calling and showing of your elements if you tell it what to do!
#using(Ajax.BeginForm(new AjaxOptions(){ LoadingElementId="divloading", OnSuccess="OnSuccessFunction" }))
{
<input type="text" name="MyText"/>
//Quick note: If you decide to hand code your html, make sure your <input/> name attributes match the property names on your model object.
//Or here you could do #Html.TextBoxFor(m => m.MyText)
<p id="PID">
Default message from declarative syntax.
</p>
<div id="divLoading" style="margin: 0px; padding: 0px; position: fixed; right: 0px;
top: 0px; width: 100%; height: 100%; background-color: #666666; z-index: 30001;
opacity: .8; filter: alpha(opacity=70);display:none" >
<p style="position: absolute; top: 30%; left: 45%; color: White;" align="center">
<img src="../../Content/themes/base/images/ajax-loading.gif"><br />
Loading, please wait...
</p>
</div>
<input type="submit" name="Submit" value="HTTPPost Button"/>
<script type="text/javascript" language="javascript">
function OnSuccessFunction(data, textStatus, jqXHR){
$("#PID")[0].innerHtml = data;
}
</script>
}
Some benefits of doing it this way is now your JS doesn't have to change if you add more properties to your model. You just add another input to your view using either the HtmlHelper or hand code the input name with the name attribute equal to the name of the property on your model. MVC will handle the rest.

Can I make mvc model validation use different error css styles for different editors?

When we use mvc model validation engine, it automatically adds certain css classes from Site.css to editors, generated by HTML helper methods; i.e.one of these for certain object:
.field-validation-error
{
color: #ff0000;
}
.field-validation-valid
{
display: none;
}
.input-validation-error
{
border: 1px solid #ff0000;
background-color: #ffeeee;
}
.validation-summary-errors
{
font-weight: bold;
color: #ff0000;
}
.validation-summary-valid
{
display: none;
}
We can surely edit these styles to apply the required styling.
But is there an opportunity to tell the model validation engine, what exact style to use, depending on any user requirements, so that we could have one page with different fields, styled differently?
EDIT
Say we have the following view:
#model ModelValidation.Models.Appointment
#{
ViewBag.Title = "Make a Booking";
}
<h2>
Book an Appointment</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<p>
#Html.LabelFor(m => m.ClientName, "Your name: ") #Html.EditorFor(m => m.ClientName)
#Html.ValidationMessageFor(m => m.ClientName)
</p>
<p>
#Html.LabelFor(m => m.Date, "Appointment Date: ") #Html.EditorFor(m => m.Date)
#Html.ValidationMessageFor(m => m.Date)
</p>
<p>
#Html.EditorFor(m => m.TermsAccepted) #Html.LabelFor(m => m.TermsAccepted, "I accept the terms & conditions")
#Html.ValidationMessageFor(m => m.TermsAccepted, null, new { #class = "other-input-validation-error" })
</p>
<input type="submit" value="Make Booking" />
}
With #Html.ValidationMessageFor overload we can specify the css class to style error message. But how can we specify css class for the editor?
I'm indeed waiting for other answers in impatience, but until that this is what I came up with.
There is a necessary overload for concrete helper methods like Html.TextBoxFor or Html.PasswordFor, etc. So the following example shows what I wanted:
#using (Html.BeginForm())
{
<p>
#{ModelState state = ViewData.ModelState["ClientName"];
}
#Html.LabelFor(m => m.ClientName, "Your name: ")
#if (state != null && state.Errors.Count > 0)
{
#Html.TextBoxFor(m => m.ClientName, new { #class = "other-input-validation-error" })
}
else
{
#Html.EditorFor(m => m.ClientName)
}
#Html.ValidationMessageFor(m => m.ClientName)
</p>
}
But I am still open to any other ideas how to do this. I'm very new to asp in general and may be easily missing (simply don't know) some nice feature of the technology.
EDIT
As it is said in Sanderson S. Freeman A. - Pro ASP.NET MVC 3 Framework Third Edition
We can’t use the templated helpers to generate an editor for a
property if we also want to provide additional attributes, so we have
used the Html.TextBoxFor helper instead and used the version that
accepts an anonymous type to use for HTML attributes.
You can always use another css file included for that specific page which overrides your settings.
To override the settings of the CSS generated by MVC, you can use a container ID like this
#container .mvc_css_class
{
display: none;
}
Another option is to use element names to increase the precedence of your own css but does not work by specifying a different ID
div.mvc_css_class
{
display: none;
}
So if you want to style a single page differently, just include your css file and set the container ID to a different value for that page, the new css settings will override based on the container .
EDIT :
To have option to override styling on every page, separate settings must be used on every page. First name the form container id differently
<div id="container-homepage">
...... the form data with original settings ..
</div>
in your css file, use the id to apply the styles you want for the homepage
#container-homepage .mv_generated_class{
color : blue;
}
Repeat the same with all the pages and classes you want to look different

Pass dynamic id's for javascript

I want to open a group with HTML-Elements when I click on a checkbox. It works fine for one group (because then i only have one id). But if I have more groups, each group has a dynamic id (for div-tag and input-tag). This is my HTML-Code:
<div style="line-height: 1.7em; background-color: #eee;">
<span style="padding-left: 8px; color: #eb8f00; font-size: 1.1em; font-weight: bold; font-family: 'Trebuchet MS', Verdana, Helvetica, Sans-Serif;">
<input style="vertical-align: middle;" id="#currentElement.sGroupId" type="checkbox" name="#currentElement.sGroupId" />
<label for="#currentElement.sGroupId">#currentElement.sGroupName</label>
</span>
</div>
<div style="background-color: #eee;" class="#currentElement.sGroupName">
<!-- Dynamic content -->
</div>
Now i have those string which are dynamic due to my foreach loop.
#currentElement.sGroupId looks like 'idgr_12' (only the number changes)
#currentElement.sGroupName is the name of the 'Group' which I want to open (the whole name changes with every loop)
This is my Javascript Code:
$(function () {
$("id from div").hide();
$("id from input").change(function () {
var $this = $(this);
if ($this.is(":checked")) {
$("id from div").show(250);
}
else {
$("id from div").hide(250);
}
});
});
Now i get for example three groups, each with a checkbox. But when I click on one checkbox each group expands. How i get these dynamic id's in my javascript method, so that only the group with the activated checkbox expands?
in your If body you can use relative selector like
$(this).parent('div').show(250)

Categories