I have an ASP.NET web forms page that uses jQuery UI tabs. Within each tab there are sets of inputs, including a button that submits the inputs within the tab (using an AJAX call, but that's not relevant to this discussion).
I want to attach the jquery validation engine (https://github.com/posabsolute/jQuery-Validation-Engine) to only the subset of inputs that comprise the tab contents, however, because of the way ASP.NET web forms works, there is only a single form element and the validation engine must attach to a form.
Is there a simple way to tell this validation engine to include the currently visible tab/elements in the validation call?
Edit to the response:
What you are looking for is even easier!!! If you simply want to validate fields on the tab the user is currently on without restricting them to go to other tabs, then ignore the tabs beforeActivate part of the code I provided, and initialize your jQuery Validation Engine to ignore validating non-visible fields which is what they will be for all non-active tabs. Your code would look like this:
jQuery("#myForm").validationEngine('attach', {
promptPosition: "bottomLeft",
validationEventTrigger: "submit",
validateNonVisibleFields: false // this does the trick!
});
Here is the new JSFiddle to illustrate the example: http://jsfiddle.net/T7daH/
Cheers! :-)
------------------------------------------------------- Original Answer -----------------------------------------------------
There is actually a pretty straightforward way to implement the jQuery Validation Engine with a form that spans multiple tabs without having to programmatically trigger validation on each field or tab click.
If you have the following form that spans multiple tabs...
<form id="myForm" action="">
<div id="tabs">
<ul>
<li>Tab 1
</li>
<li>Tab 2
</li>
<li>Tab 3
</li>
</ul>
<div id="tabs-1">
<input type="text" id="requiredFiled" name="requiredField" class="validate[required]" />
</div>
<div id="tabs-2"></div>
<div id="tabs-3"></div>
</div>
Then you set up the form and tabs like this:
jQuery("#myForm").validationEngine('attach', {
promptPosition: "bottomLeft",
validationEventTrigger: "submit",
validateNonVisibleFields: true,
updatePromptsPosition: true
});
$(function () {
$("#tabs").tabs({
beforeActivate: function (event, ui) {
if (!$("#myForm").validationEngine('validate')) {
event.preventDefault();
$('#myForm').validationEngine('hide');
setTimeout(function () {
$("#myForm").validationEngine('validate');
}, 450);
}
}
});
});
The result is that the user cannot select another tab if the tab the user is currently on is not fully valid. Here is the JSFiddle demo: http://jsfiddle.net/g9yLL/36/
Cheers! :-)
I had a website with a form with multi-tab and solved it using this:
$(document).ready(function(){}
$('#tab1').click(function(){
// #tab1 name of the tab / a href link inside that tab
var field1 = $("#field1").validationEngine('validate');
var field2 = $("#field2").validationEngine('validate');
if(field1 || sources )
{ // to show the error messages ;
return false;
}
});
$('#tab2').click(function(){
// #tab2 name of the tab / a href link inside that tab
var field1 = $("#field1").validationEngine('validate');
var field2 = $("#field2").validationEngine('validate');
if(field1 || field2 )
{ // to show the error messages ;
return false;
}
});
);
For more information check https://github.com/posabsolute/jQuery-Validation-Engine and search for field validation under validate heading.
Related
I am new to ASP.NET MVC. I am facing one or other issues to design the layout for below scenario. Could you someone help me with a solution and I will definitely appreciate your help.
The requirement is:
This is an existing application. While loading view there is a Master View and inside few partial views already defined.
In one of the Partial view, I need to have a same layout multiple times on demand. It is depends on the user how many required. may be 1 or 2 or more. We are using Telerik Kendo controls extensively in our UI and in existing View we strongly typed Model object with View.
I would like to go with Kendo Tabstrips control and add Tab dynamically when required by the user. Also, the layout is exactly same, So, would like to design (Html table with many controls like textbox, dropdown etc.) each tab layout as Partial View so that I can reuse the design. Please let me know whether this approach is best or any better approach is available.
I need to get the entire data when the user Submit the master view . Each main partial View contains and the parent of the Tabstrips Partial view also contains a but not defined for each tabstrip partial view as I need data as collection of objects in one of the property in Parent Partial View Model Object.
Can you please let me know how to design model object for each tabs(Partial View) as well as Parent Partial View. it could be good, if you could show a small example code.
The below are the issues faced during designing this
Unable to add inside another as getting below error
Inline markup blocks (#Content) cannot be nested. Only one level of inline markup is allowed.
#(Html.Kendo().PanelBar().Name("panelBar_" + panelName).Items(pb => pb.Add().Text("PCG").Expanded(Expanded).Selected(true)
.Content(#<text>
<form id="frm_#(panelName)" onsubmit="DisableEvent(event)">
<div style="width:100%; height:auto;">
<button class="k-button">Add new PCG</button>
#(Html.Kendo().TabStrip()
.Name("TabPCG").HtmlAttributes(new { style = "width:100%;" })
.Items(items =>
{
items.Add()
.Text("PCG 1 <button data-type='remove' class='k-button k-button-icon' onclick='deleteMe(this)'><span class='k-icon k-i-close'></span></button>")
.Encoded(false)
.Selected(true)
.HtmlAttributes(new { style = "width:12%", id = "tabPCG1" })
//.LoadContentFrom("_PCGTab", "Home", new { tabId ="tab1"});
.Content(#<text>#(Html.Partial("_PCGTab"))</text>);
})
)
</div>
</form>
</text>)))
2.Then Changed the design as shown below. defined partial view in Parent View
#helper RenderPCGTab()
{
<div style="width:100%; height:auto;">
<button class="k-button">Add new PCG</button>
#(Html.Kendo().TabStrip()
.Name("TabPCG").HtmlAttributes(new { style = "width:100%;" })
.Items(items =>
{
items.Add()
.Text("PCG 1 <button data-type='remove' class='k-button k-button-icon' onclick='deleteMe(this)'><span class='k-icon k-i-close'></span></button>")
.Encoded(false)
.Selected(true)
.HtmlAttributes(new { style = "width:12%", id = "tabPCG1" })
//.LoadContentFrom("_PCGTab", "Home", new { tabId ="tab1"});
.Content(#<text>#(Html.Partial("_PCGTab"))</text>);
})
)
</div>
}
and designed Kendo panel as shown below the Parent Partial View
#(Html.Kendo().PanelBar().Name("panelBar_" + panelName).Items(pb => pb.Add().Text("PCG").Expanded(Expanded).Selected(true)
.Content(#<text>
<form id="frm_#(panelName)" onsubmit="DisableEvent(event)">
#RenderPCGTab()
</form>
</text>)))
Since you use a strongly typed View, I would recommend using a Tuple as the model.
The Item1 would hold the required model details, while Item2 would hold the required number of tabs (it holds the names of the tabs).
#model Tuple<[Model],List<string>>
Now create a Kendo Tabstrip control, with dynamic items (based on model's Item2)
#(Html.Kendo().TabStrip()
.Name("KendoTabStrip") //You need to dynamically change the name by appending a unique parameter in case you need multiple Tabstrips
.Animation(animation =>
animation.Open(effect =>
effect.Fade(FadeDirection.In)))
.Items(tabstrip =>
{
var TabItemIndex = 0;
foreach (var TabItem in Model.Item2)
{
tabstrip.Add().Text(TabItem)
.Selected(false)
.HtmlAttributes(new { id = "TabStripButton" + TabItem + "_" + TabItemIndex, title = TabItem}) //Generate a dynamic ID for each Tab
.Content(" ");
TabItemIndex++;
}
})
)
Once you have created the structure of the Tabstrip, you need to populate each tab with its corresponding content
In the View (Parent Partial View) itself, create a Ready function for the tabstrip and serialize the object using JSON
$(("KendoTabStrip")).ready(function () {
_TBSModelName = #Html.Raw(JsonConvert.SerializeObject(this.Model.Item1))
TabStripUserControl();
});
Note: This is in case you need the Model Data in your child partial view.
Create a javascript file and place the function TabStripUserControl() in it. This function will create your content and place it into the tab.
function TabStripUserControl()
{
var _LocalTBSModel = _TBSModelName
var items = "#KendoTabStrip" + " .k-tabstrip-items";
$(items).click(function (z) {
}
);
}
Inside the function (click function), create a div and provide a dynamic ID for the same before placing it inside the tab using Javascript/JQuery.
var div = $("<div/>");
Use Ajax call to call your controller, which in turn will call your Child Partial View (which contains HTML controls) and render the partial view inside the above created div on Ajax call's success.
$.ajax({
url: 'Controller/ActionMethod',
data: JSON.stringify({ Value: "SomeValue" }),
type: 'POST',
contentType: 'application/json;',
async: false,
success: function (data) {
div = data;
}
});
Hope this helps.
i want a anchor should act like and input type submit button.
i am using a jquery plugin library that actually uses input type submit but i have styled my buttons on anchors. i dont want to use
<input type="button">
or
<input type="submit">
i want to use anchors such as
<a href="javascript to submit the form" ></a>
and here is my jquery code where i want to use
{
var submit = $('<button type="submit" />');
submit.html(settings.submit);
}
$(this).append(submit);
}
if (settings.cancel) {
/* if given html string use that */
if (settings.cancel.match(/>$/)) {
var cancel = $(settings.cancel);
/* otherwise use button with given string as text */
} else {
var cancel = $('<button type="cancel" />');
how to use anchors instead of button.
If you want an anchor tag to act like a button just do this
<!--YOUR FORM-->
<form id="submit_this">.....</form>
<a id="fakeanchor" href="#"></a>
<script>
$("a#fakeanchor").click(function()
{
$("#submit_this").submit();
return false;
});
</script>
Since you're using jQuery, just use $() to select the form element, and call submit on it; hook all this up to the anchor via $() to find the anchor and click to hook up the handler:
$("selector_for_the_anchor").click(function() {
$("selector_for_the_form").submit();
return false;
});
Probably best to return false; to cancel the click on the anchor.
Off-topic: But note that this makes your page completely unusable without JavaScript, as well as making it confusing even for JavaScript-enabled browsers employed by users requiring assistive technologies (screenreaders, etc.). It makes the markup completely un-semantic. But since you'd said quite clearly that this was what you wanted to do...
<a id='anchor' href="javascript to submit the form" ></a>
now you can use jquery to add an event handler
$('#anchor').click(function (e) {
// do some work
// prevent the default anchor behaviour
e.preventDefault();
})
now you can style your anchor as you wish and it will act as a regular button
And what about:
<form id="formOne">
...
link here
</form>
you can use input of type image (it works as a submit button for a form) or in jquery:
$("a").click(function(event){
event.preventDefault();
$('form').submit();
})
I'm looking for alternative ways of solving a problem. We're using ElFinder for browsing files, and we want to allow the user to change the access rights to a file element through the right-click context menu ("Change permissions"). The solution I have come up with so far is to load a server side ASP.NET usercontrol in a jQuery modal dialog window. This user control will contain the logic needed to add / remove user access to the selected element.
The jQuery Dialog script looks like this (slightly changed for readability), where DisplayItemAccessConfig() is the method that's called from the context menu:
<!-- access control script -->
<script type="text/javascript" charset="utf-8">
function DisplayItemAccessConfig() {
$.getJSON('AccessRights.ashx', function (data) {
var itemName = data["itemName"];
/* set new title (JUST FOR TESTING) */
$(dialog).dialog('option', 'title', itemName);
/* open modal dialog --> */
$(dialog).dialog('open');
});
}
$(function () {
$("#dialog").dialog({
autoOpen: false,
modal: true,
buttons: {
"Ok": function () { $(this).dialog("close"); },
"Cancel": function () { $(this).dialog("close"); }
},
open: function (type, data) {
$(this).parent().appendTo("form");
}
});
});
</script>
Challenge 1: find a way to reload the user control each time the jQuery popup is displayed - this is to retrieve the current access settings for the selected element. Now it loads when the page is first loaded, since it's just a div element containing an update panel with a placeholder for my usercontrol and visibility set to none. Anyone have any tips here?
Challenge 2: While I am trying to figure that one out I thought it could be worth while asking for other opinions. Is there a better way of solving this? Should I use a pure jQuery with HTML and call server side .ashx methods to retrieve data, instead of an ASP.NET usercontrol?
You can do this by creating a hidden button on inside the uploadpanel and then trigger it like this:
__doPostBack('<%= Button.ClientID %>','');
Personally I would drop the UpdatePanel and go for jQuery AJAX calls to update the content of the dialog window, but this depends on the complexity of your user control. Hard to say without seeing more of your code.
I'm trying to create a single page form to create a 'work item'. One of the properties is a drop down for 'work item type'.
Depending on the work item type, the user may need to provide additional information in a name-value-pair style attributes grid (property sheet).
I would like to dynamically render the property sheet as soon as a work item type is selected or changed. Once the user provides all information, he would click submit to create the 'work item'.
This is what I have so far:
#using (Ajax.BeginForm("AttributeData", new AjaxOptions() { UpdateTargetId="AttributeDataCell" }))
{
<div style="float:left">
#{
Html.RenderPartial("CreateWorkItemPartialView");
}
</div>
<div id="AttributeDataCell" style="float:right">
#Html.Action("AttributeData", new {id = 1})
</div>
}
The AttributeData action in the controller simply renders the partial view:
public ActionResult AttributeData(int id = 0)
{
var attributes = _workItemDataService.ListWorkItemTypeAttributes(id);
return PartialView("EditWorkItemAttributesPartialView", attributes);
}
Now I would like to hook this up to the drop-down-list's selection event so that the partial view re-renders in the above table cell at every selection change. I would like to pass in the selected value as id.
One way is to force the form to submit itself (and thus re-render).
If that is the right approach, how do we go about it? Esp., how do we make only the property sheet to re-render?
If there is a better way to achieve the above, please indicate.
Thanks
You could subscribe to the .change() event of the dropdown and trigger an AJAX request:
$(function() {
$('#Id_Of_Your_Drop_Down').change(function() {
// This event will be triggered when the dropdown list selection changes
// We start by fetching the form element. Note that if you have
// multiple forms on the page it would be better to provide it
// an unique id in the Ajax.BeginForm helper and then use id selector:
var form = $('form');
// finally we send the AJAX request:
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: form.serialize(),
success: function(result) {
// The AJAX request succeeded and the result variable
// will contain the partial HTML returned by the action
// we inject it into the div:
$('#AttributeDataCell').html(result);
}
});
});
});
I have a web form in SPARK which allow the editing of a Facility class that contains Rooms. When editing the Facility all the Rooms are listed for editing too. The form works fine for editing, but I would like to include a button "Add Room" that adds a new blank room below the existing ones. Any idea how this is accomplished?
Currently I am doing this in my SPARK page:
[All the Facility editing stuff...]
<p>Room</p>
<div class="small">Enter the rooms associated with this facility.</div>
<div class="add">
<div id="room">
<AddFacilityRoom each="var roomModel in Model.FacilityRooms" RoomModel="roomModel" Index="roomModelIndex" />
</div>
<a id="addRoom" class="add" href="events/room/add.mvc">Add a room</a>
</div>
AddFacilityRoom contains the html elements for editing a room.
I would like add.mvc to create a new empty Room class and inject a new identical (but empty) control below the existing ones. Currently, though it opens a new page when the "Add a Room" button is clicked.
Ok, I figured this out. I was missing the JQuery knowledge to understand this. The function below:
$('#addRoom').click(function () {
var a = $(this);
a.addClass('loading');
$.ajax({
url: a.attr('href'),
cache: false,
success: function (html) {
$('#room').append(html);
a.removeClass('loading');
}
});
return false;
});
Plus, the following HTML:
<div id="room">
<a id="addRoom" class="add" href="events/room/add.mvc">Add a room</a>
</div>
Does the trick.
Your solution looks nice, but since you are using Spark, you could consider the rarely mentioned Javascript templates. The advantage of this being that the markup in _AddFacilityRoom.spark would not need to be duplicated in add.mvc. Nor would a json request be required (if no data needed for new room).
I'll sadly forgotten exactly how they work, but the steps are something like:
Add a new action:
public ActionResult AddRoomScript()
{
return new JavascriptViewResult { ViewName = "_AddFacilityRoom" };
}
Add a script tag with: src="!{Url.Action("AddRoomScript")}"
Then some js to call and set:
var html = Spark.Shared._AddFacilityRoom.RenderView( { RoomModel = {} );
$('#room').append(html);
Some research would be needed to get that working correctly, but it's an interesting option.