I am using JQuery tabs in my Asp.Net/C# app.
I am modelling my approach after this article. The JQuery is outside of my
<asp:UpdatePanel ID="UpdatePanel1"...></asp:UpdatePanel>
wrapper while the html components are inside.
Whenever I click a button, my tabs completely lose their CSS styling and I see all of the tab contents, rather than just the
<div id="current-tab">
for that tab.
Why is this happening and how do I fix it?
My guess is that its related to post-back or the update panel somehow, but I am not sure why the added C# code under page_load doesn't keep the selected tab current on post-back when the button is fired.
ASPX
<link href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.9/themes/start/jquery-ui.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.9/jquery-ui.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
var tabs = $("#tabs").tabs({
activate: function (e, i) {
selected_tab = i.index;
}
});
selected_tab = $("[id$=selected_tab]").val() != "" ? parseInt($("[id$=selected_tab]").val()) : 0;
tabs.tabs('select', selected_tab);
$("form").submit(function () {
$("[id$=selected_tab]").val(selected_tab);
});
...
</script>
....
<table>
<tr>
<td style="padding: 5px;">
<div id="tabs">
<ul>
<li>Tier 1</li>
<li>Tier 2</li>
<li>Tier 3</li>
<li>Tier 4</li>
</ul>
<div class="tab-content">
<div id="tab-1">
...
</div>
<div id="tab-2">
...
</div>
<div id="tab-3">
...
</div>
<div id="tab-4">
...
</div>
</div>
</div>
<asp:HiddenField ID="selected_tab" runat="server" />
</td>
</tr>
</table>
C#
protected void Page_Load(object sender, EventArgs e)
{
...
selected_tab.Value = Request.Form[selected_tab.UniqueID];
...
}
You are right, it has something to do with a Partial PostBack. So in order for jquery functions to work again you need to rebind it after the Partial PostBack is done.
<script type="text/javascript">
$(document).ready(function () {
buildTabs();
});
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
buildTabs();
});
function buildTabs() {
var tabs = $("#tabs").tabs({
activate: function (e, i) {
selected_tab = i.index;
}
});
selected_tab = $("[id$=selected_tab]").val() != "" ? parseInt($("[id$=selected_tab]").val()) : 0;
tabs.tabs('select', selected_tab);
$("form").submit(function () {
$("[id$=selected_tab]").val(selected_tab);
});
}
</script>
But the selected tab is a different story. You also need to store the active tab somewhere and re-apply it after the partial PostBack is done. See this answer for details.
But basically you need to store the active tab ID in SessionStorage, cookie or Hiddden input and re-apply it in prm.add_endRequest(function () {
Related
I am trying to use the sample off of jqWidgets for the ListBox. I have copied the code directly into my index.cshtml file. I am not seeing the desired results, which would be what the sample looks like. All it is showing me is the button.
Here is a link to the page. I have reduced the content and allowed for anyone to look at it: https://drive.azurewebsites.net/Question
Here is the sample's website: http://www.jqwidgets.com/jquery-widgets-documentation/documentation/jqxlistbox/jquery-listbox-getting-started.htm
I'm not sure how to troubleshoot this or where to look to see what is really going wrong. I am using Chrome and pulled up Inspect Element. The scripts are being retrieved.
Here is my code:
<link rel="stylesheet" href="~/Scripts/jqwidgets/styles/jqx.base.css" type="text/css" />
<script type="text/javascript" src="~/Scripts/jqwidgets/jqxcore.js"></script><script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="~/Scripts/jqwidgets/jqxbuttons.js"></script>
<script type="text/javascript" src="~/Scripts/jqwidgets/jqxscrollbar.js"></script>
<script type="text/javascript" src="~/Scripts/jqwidgets/jqxlistbox.js"></script>
<body>
<div id='content'>
<script type="text/javascript">
$(document).ready(function () {
var source = [
"Affogato",
"Americano",
"Bicerin",
"Breve",
"Café Bombón",
"Café au lait",
"Caffé Corretto",
"Café Crema",
"Caffé Latte",
];
// Create a jqxListBox
$("#jqxlistbox").jqxListBox({ source: source, width: '200px', height: '200px' });
// disable the sixth item.
$("#jqxlistbox").jqxListBox('disableAt', 5);
// bind to 'select' event.
$('#jqxlistbox').bind('select', function (event) {
var args = event.args;
var item = $('#jqxlistbox').jqxListBox('getItem', args.index);
$("#eventlog").html('Selected: ' + item.label);
});
$("#button").jqxButton();
$("#button").click(function () {
var item = $('#jqxlistbox').jqxListBox('getSelectedItem');
if (item != null) {
alert(item.label);
}
});
});
</script>
<div id='jqxlistbox'>
</div>
<div style="margin-top: 10px;">
<input id="button" type="button" value="Get Selected Item" />
<div id="eventlog"></div>
</div>
</div>
</body>
Your Scripts are not referenced correctly. In MVC4, the process of referencing Scripts is different - http://www.jqwidgets.com/jquery-widgets-documentation/documentation/asp.net-integration/asp.net-binding-to-sql-database-mvc4.htm
I have some listed tab controls on my aspx form which is as below
<div id="tabs">
<ul>
<li>Tab A</li>
<li>Tab B</li>
<li>Tab C</li>
</ul>
<div id="tabs-1"></div>
<div id="tabs-2"><asp:Button ID="someid" runat="server"/></div>
<div id="tabs-3"></div>
</div>
The navigation on mouse click on a tab is done by the following:
<script type="text/javascript">
$(function () {
$("#tabs").tabs();
});
</script>
Now, my question is, How can i maintain the selected tab as it is even after postback.
For Example, I select Tab B that contains a Button which causes a postback on click.
After the postback occurs Tab A regians the foucs and i have to manually select Tab B for adjuvent operations.
Please help me to solve this problem.
I think this Code will help you...
<div id="tabs">
<asp:HiddenField ID="hidtab" Value="0" runat="server" />
<ul>
<li>Tab 1</li>
<li>Tab 2</li>
</ul>
<div id="tabs-1">
<asp:Button ID="Button1" runat="server" Text="Submit" OnClick="Button1_Click"/>
</div>
<div id="tabs-2">
<asp:Button ID="Button2" runat="server" Text="Submit" OnClick="Button2_Click"/>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
var st= $(this).find("input[id*='hidtab']").val();
if (st== null)
st= 0;
$('[id$=tabs]').tabs({ selected: st});
});
</script>
protected void Button1_Click(object sender, EventArgs e)
{
hidtab.Value = "0";
}
protected void Button2_Click(object sender, EventArgs e)
{
hidtab.Value = "1";
}
Initialize tabs with the cookie option specified. Sample
$(function () {
$("#tabs").tabs({ cookie: { expires: 30 } });
});
You need the jQuery Cookie plugin..
You can track it by your URL like they did in this post.
The following code is just for example and can be done a lot nicer. I used the active property from the jquery ui tabs. it works with the index of the element but perhaps its working with the #hash aswell did not test it. so in the example below i get the index of the tab and use it with active property;
<div id="tabs">
<ul>
<li>Tab A</li>
<li>Tab B</li>
<li>Tab C</li>
</ul>
<div id="tabs-1"></div>
<div id="tabs-2"><asp:Button ID="someid" runat="server"/></div>
<div id="tabs-3"></div>
</div>
<script type="text/javascript">
$(function () {
var tabsOpts = {},
activeTab, activeTabIndex,
urlCheck = doucment.location.href.split('#');
// urlCheck is an array so when there is more then one result
// there is a hash found in the URL
if( urlCheck.length > 1 ) {
activeTab = urlCheck[1];
// getting the index from the link
activeTabIndex = $("#tabs li a[href="+ activeTab +"]").index();
// create new object options for the tabs
tabsOpts = { active: activeTabIndex };
}
$("#tabs").tabs(tabsOpts)
.find('li a').each(function() {
// get URL from the tab href
var href = $.data(this, 'href.tabs');
// set URL with the href from your tab
document.location = href;
});
});
</script>
Client Side solution:
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(IniciaRequest);
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
var currentTab;
function IniciaRequest(sender, arg) {
var _Instance = Sys.WebForms.PageRequestManager.getInstance();
if (_Instance.get_isInAsyncPostBack()) {
window.alert("Existe un proceso en marcha. Espere");
arg.set_cancel(true);
}
}
function BeginRequestHandler(sender, args) {
//Persiste el valor del indice del TAB actual del control Jquery para mantener el tab actual seleccionado luego del Postback.
if ($get('hdCurrentTab') != null) {
currentTab = $get('hdCurrentTab').value;
}
//----
}
function EndRequestHandler(sender, args) {
//Permite visualiza el control JQuery TAB dentro de ventanas modales AJAX.
if (sender._postBackSettings.panelsToUpdate != null) {
$("#tabs").tabs();
//Persiste el valor del indice del TAB actual del control Jquery para mantener el tab actual seleccionado luego del Postback.
if ($get('hdCurrentTab') != null) {
$get('hdCurrentTab').value = currentTab;
$("#tabs").tabs({ active: currentTab });
}
//----
}
//----
}
</script>
HTML on Page:
<input id="hdCurrentTab" type="hidden" value="0" />
<div id="tabs" style="width:97%;margin: auto; font-family: verdana, tahoma, arial, sans-serif; font-size: 11px;">
<ul>
<li>TAB1</li>
<li>TAB2</li>
</ul>
<div id="tabs-1"></div>
<div id="tabs-2"></div>
</div>
TAB remains selected after postbacks.
I am trying to create an alert as described in this site http://needim.github.com/noty/
and here is the code
<head runat="server">
<title>Test</title>
<script src="jquery-1.7.2.min.js" type="text/javascript"></script>
<script type="text/javascript" src="js/noty/jquery.noty.js"></script>
<script type="text/javascript" src="js/noty/layouts/top.js"></script>
<link rel="stylesheet" type="text/css" href="buttons.css" />
<script type="text/javascript" src="js/noty/themes/default.js"></script>
</head>
<body>
<div class="container">
<div id="customContainer">
</div>
</div>
<script type="text/javascript">
function generate(type, layout) {
var n = noty({
theme: 'defaultTheme',
text: 'Do you want to continue?',
buttons: [
{
addClass: 'btn btn-primary',
text: 'Ok',
onClick: function ($noty) {
// this = button element
// $noty = $noty element
$noty.close();
noty(
{
text: 'Record deleted !',
type: 'success',
callback:
{
onShow: function () { },
afterShow: function () { TakeValue(true); },
onClose: function () { },
afterClose: function () { }
}
});
}
},
{
addClass: 'btn btn-danger',
text: 'Cancel',
onClick: function ($noty) {
$noty.close();
noty(
{
text: 'Record not deleted !',
type: 'warning',
callback:
{
onShow: function () { },
afterShow: function () { TakeValue(false); },
onClose: function () { },
afterClose: function () { }
}
});
}
}
]
});
}
function TakeValue(result) {
if (result == true) {
document.getElementById("Hidden1").value = "true";
alert(document.getElementById("Hidden1").value);
} else {
document.getElementById("Hidden1").value = "false";
alert(document.getElementById("Hidden1").value);
}
}
function generateAll() {
generate('information', 'top');
}
</script>
<form id="form" runat="server">
<input id="Hidden1" type="hidden" value="false"/>
<asp:Button ID="Button2" runat="server" Text="Press" OnClientClick="return generateAll();" />
<input id="Button1" type="button" value="button" onclick="return generateAll();" />
</form>
</body>
I have placed two buttons ,one is HTML button while the other is of asp:Button,
The whole scenario just works fine when I use the HTML button ,but the page is not displaying the similar behavior in case of asp:Button click, I have placed a test function in JavaScript to test the OnClientClick event of the asp:Button and that worked fine,but I don't know why this alert is not getting called, I think there is some problem with the Noty JS.
Kindly give feed back
thanks.
As jbabey said in the comments:
an asp:button will cause a postback when clicked by default. you need to return false from the onclientclick, right now you are returning undefined since generateAll has no return.
Since you're using jQuery, I'd go one step further and not directly set the click attribute. Instead, set it using jQuery:
<script>
$(document).ready(function() {
$('#Button1').click(generateAll);
});
...
function generateAll(e) {
generate('information', 'top');
// This will prevent the default action of submitting the form.
e.preventDefault();
}
</script>
Could you please add UseSubmitBehavior="false" attribute to the asp:button.
<asp:Button ID="Button2" runat="server" Text="Press" UseSubmitBehavior="false" OnClientClick="return generateAll();" />
I hope this will resolve your issue. Please let me know whether it helped you or not.
I have a dropdownlist control ddlAffilation, a panel pnlForms, a panel Complete, a button Submit, a button Return.
I have a validationcontrol on the dropdownlist.
here is my jquery code
<script type="text/javascript">
$(document).ready(function () {
$("#<%= Submit.ClientID %>").click(function () {
$("#<%= pnlForms.ClientID %>").fadeOut('slow');
$("#Complete").delay(800).fadeIn('slow');
});
$("#<%= Return.ClientID %>").click(function () {
$("#Complete").fadeOut('slow');
$("#<%= pnlForms.ClientID %>").delay(800).fadeIn('slow');
});
});
</script>
I have 2 problems:
1) With this jQuery code, I can go back and forth (fade out pnlForms, fade in Complete when click on Submit and vice versa when click on Return) only when i don't choose any value in the dropdownlist box. If I choose any value in the dropdownlist, the Return button doesn't work.
2) The jquery code bypass the .net server validation control. I need the code not do anything if no value is selected from the dropdownlist. I have tried
var isValid = true;
if ($("#<%= ddlAffilation.ClientID %>").val() == "") {
isValid = false;
return false;
}
if (isValid == true) {
...
but it doesn't work. What's the best way to do this?
Thanks,
==================================================================================
I can't add an answer to my own question so I reply to John here:
Thanks John. I have my code like this and it solves problem 2.
<script type="text/javascript">
$(document).ready(function () {
$("#<%= Submit.ClientID %>").click(function (e) {
if (IsValid() == false) {
e.preventDefault();
return false;
}
else {
$("#<%= pnlForms.ClientID %>").fadeOut('slow');
$("#Complete").delay(800).fadeIn('slow');
}
});
$("#<%= Return.ClientID %>").click(function () {
alert('blah2');
$("#Complete").fadeOut('slow');
$("#<%= pnlForms.ClientID %>").delay(800).fadeIn('slow');
});
function IsValid() {
// Add any other validation in here
if ($("#<%= ddlAffilation.ClientID %>").val() == "") {
return false;
}
return true;
}
});
</script>
However, problem 1 still exists. Let me clarify. I have a few textboxes, a dropdownlist and a submit button to collect feedback from the users. They are all in the panel pnlForms.
All controls can be empty except for the dropdownlist. We took care of this using your code and a server validation control.
when the users click the submit button, I want the pnlForms to fadeOut and a hidden panel called pnlComplete to fadeIn. The pnlComplete has a text saying thanks for the feedback and a button called Return that let the users send another feedback.
When the users click on the Return button, the opposite happens here. The pnlComplete fadeOut and the pnlForms fadeIn.
The Submit button works well but the Return button doesn't work at all. I set some alert() inside the Return.click(function but it doesn't hit.
Any ideas?
Here is the code of the whole page.
<%# Page Title="" Language="C#" MasterPageFile="~/Master.master"
AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Default" %>
<asp:Content ID="Content1" ContentPlaceHolderID="content" runat="Server">
<asp:UpdatePanel ID="pnlForms" runat="server">
<ContentTemplate>
<fieldset>
<legend>Your Information</legend>
<ol>
<li>
<label for="ctl00_content_name">
Your Name:</label>
<asp:TextBox ID="Name" runat="server" Width="150px"></asp:TextBox>
<em class="optional">Optional </em></li>
<li>
<label for="ctl00_content_status">
Your Affiliation:*</label>
<asp:DropDownList ID="ddlAffilation" runat="server" Width="155px">
<asp:ListItem Text="--Select One--" Value="" Selected="True" />
<asp:ListItem>F</asp:ListItem>
<asp:ListItem>S</asp:ListItem>
<asp:ListItem>T</asp:ListItem>
</asp:DropDownList>
<em class="required">Required
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage=" - Please select your affiliation"
ControlToValidate="ddlAffilation" SetFocusOnError="True" ForeColor=""></asp:RequiredFieldValidator>
</em></li>
</ol>
</fieldset>
<div style="text-align: center;">
<asp:Button ID="Submit" runat="server" Text="Submit" OnClick="submit_Click" /></div>
</ContentTemplate>
</asp:UpdatePanel>
<div id="Complete" style="display: none;">
<asp:UpdatePanel ID="pnlComplete" runat="server">
<ContentTemplate>
<p>Thank you</p>
<div style="text-align: center;">
<asp:Button ID="Return" runat="server" Text="Return" /></div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</asp:Content>
<asp:Content ID="Content3" runat="server" ContentPlaceHolderID="cpClientScript">
<script type="text/javascript">
$(document).ready(function () {
$("#<%= Submit.ClientID %>").click(function (e) {
if (IsValid() == false) {
e.preventDefault();
return false;
}
else {
$("#<%= pnlForms.ClientID %>").fadeOut('slow');
$("#Complete").delay(800).fadeIn('slow');
}
});
$("#<%= Return.ClientID %>").click(function () {
$("#Complete").fadeOut('slow');
$("#<%= pnlForms.ClientID %>").delay(1000).fadeIn('slow');
});
function IsValid() {
// Add any other validation in here
if ($("#<%= ddlAffilation.ClientID %>").val() == "") {
return false;
}
return true;
}
});
</script>
</asp:Content>
I'm not sure if I read your question right or not, but if your issue is that you don't want the jquery to continue firing and allow the form to submit if the dropdown is empty do this:
Instead of attaching a .click event to your button, attach a .submit event to your form. Then you want to use e.PreventDefault() to stop the main submit execution if its not valid
Eg:
$("#FORMNAME").submit(function(e) {
if (IsValid() == false) {
e.preventDefault();
return false;
}
// Submitting form...
}
function IsValid() {
// Add any other validation in here
if ($("#<%= ddlAffilation.ClientID %>").val() == "") {
return false;
}
return true;
}
Also, you should ALWAYS do server validation along with your client validation.. otherwise all someone has to do is directly submit / bypass your javascript checks
Edit for your edit:
Is the return button being created dynamically or is it there on page load? If its dynamic, its probably never getting assigned to in your jquery, as it doesn't exist when it runs.
Here is a quick test you could try:
var returnButton = $("#<%= Return.ClientID %>");
alert(returnButton.attr("id");
If you don't get back the ID of your return button, its not matching up in your code and thats why your click event isn't working. If thats the case, do a view source on your page and find out what the actual return button ID is set to (this is easier with FireBug or similar tool)
Adding this as a separate answer since its just a huge chunk of code that isn't exactly related to the original answer, but does work as intended. I took the code you gave and converted to basic html from asp.net, and it does work correct, does it work for you?
Could you try posting the output from the asp.net page instead of the code itself? Maybe something isn't being set right on the button element's ID.
<html>
<head>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.js" type="text/javascript"></script>
</head>
<body>
<div ID="Content1">
<div ID="pnlForms">
<fieldset>
<legend>Your Information</legend>
<ol>
<li>
<label for="ctl00_content_name">
Your Name:</label>
<textbox ID="Name" runat="server" Width="150px"></TextBox>
<em class="optional">Optional </em></li>
<li>
<label for="ctl00_content_status">
Your Affiliation:*</label>
<select ID="ddlAffilation" Width="155px">
<option Value="" Selected="True">--Select One--</option>
<option>F</option>
<option>S</option>
<option>T</option>
</select
</li>
</ol>
</fieldset>
<div style="text-align: center;">
<Button ID="Submit" Value="Submit" OnClick="submit_Click">Submit</Button></div>
</div>
<div id="Complete" style="display: none;">
<div ID="pnlComplete">
<p>Thank you</p>
<div style="text-align: center;">
<Button ID="Return" Value="Return">Return</Button></div>
</div>
</div>
</div>
<div ID="Content3">
<script type="text/javascript">
$(document).ready(function () {
$("#Submit").click(function (e) {
if (IsValid() == false) {
e.preventDefault();
return false;
}
else {
$("#pnlForms").fadeOut('slow');
$("#Complete").delay(800).fadeIn('slow');
}
});
$("#Return").click(function () {
$("#Complete").fadeOut('slow');
$("#pnlForms").delay(1000).fadeIn('slow');
});
function IsValid() {
// Add any other validation in here
if ($("#ddlAffilation").val() == "") {
return false;
}
return true;
}
});
</script>
</div>
</body>
</html>
I need to insert some JavaScript code inside a UserControl that I load from an Ajax call via jQuery Ui Tabs. Let me explain...
This is my View (with jQuery loaded)
<script type="text/javascript">
$(document).ready(function () {
$("#tabs").tabs({
cache: false,
});
getContentTab (1);
});
function getContentTab(index) {
var url='<%= Url.Content("~/Home/getUserControl") %>/' + index;
var targetDiv = "#tabs-" + index;
$.get(url,null, function(result) {
$(targetDiv).html(result);
});
}
</script>
<div id="tabs">
<ul>
<li>Nunc tincidunt</li>
<li>Proin dolor</li>
<li>Aenean lacinia</li>
</ul>
<div id="tabs-1">
</div>
<div id="tabs-2">
</div>
<div id="tabs-3">
</div>
</div>
With these lines of code I call the Ajax function to load the content into a DIV.
This is the Action from the controller:
public ActionResult getUserControl(int num)
{
return PartialView("TestUC", num);
}
And this is the UserControl...
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
Number... <span id="testSpan"><%=Model.ToString() %></span>!!
<input type="button" value="Click me!!" onclick="message();" />
<script type="text/javascript">
function message(item) {
alert($("#testSpan").html());
}
</script>
The problem is that the message() function returns always 1 (instead of returning the correct number).
My question is... How should I add the script to my UserControl in order to have my code running correctly?
I'm just guessing here.
I guess your problem is that when a tab is loaded, it stays in the DOM even if you open another one (i.e. If the #1 is the default, it will remain loaded even if you click on the second one).
If this is happening, when you call the message function, there will be multiple elements with the id "testSpan", and the jQuery selector $("#testSpan") will return the first of them.
I suppose this is just some test code, but for this particular case I would go with adding the <%= Model.ToString() %> as an argument to the javascript function.
Again, I'm just guessing about the behavior of the jquery-ui tabs() function.
Regards
Try Adding script like this
<script type="text/javascript" defer="defer">
function message(item) {
alert($("#testSpan").html());
}
</script>