How to render/not render Close link of Jquery dialog box? - ajax

I have/can have only one Jquery dialog box. This dialog box has some advertisement content to the User.
On reading it, a User can avail the offer or ignore it for the time being.
User can avail the offer by clicking on Submit button inside the dialog box.
Or he can ignore it by clicking on "Remind me later" link which will close the dialog box.
Contents inside dialog box are updated through Ajax. So when Submit button is clicked,
a thank you message is shown inside the same dialog box.
When User avails the offer, "Remind me later" link would still be there. If User clicks on that, logically, dialog
box should be shown again. But, User has already availed the offer!
How can I render or not render Close link of Jquery dialog box programatically?
Code for dialog box is below,
$h(document).ready(function() {
$h("#showForm").dialog({
open: function(event, ui) {
jQuery('.ui-dialog-titlebar-close').html('<span>Remind me later</span>');
jQuery('.ui-dialog-content').removeClass("ui-dialog-content").addClass("advertise-upgrade-content");
},
duration: 800,
height: 727,
minWidth: 811,
width: 811,
position: ['middle', 154],
zIndex: 99999999,
modal: true,
show: {
effect: 'puff',
duration: 400
},
hide: {
effect: 'puff',
duration: 400
}
});
});
<div id="showForm" height: 670px;">
<div class="submitClass">
<a4j:commandLink immediate="true" action="#{myBean.clickToAvail}" reRender="renderSuccess" value="Submit">
</a4j:commandLink>
</div>
<h:panelGroup id="renderSuccess">
<h:outputText value="Thank you for availing this offer">
</h:panelGroup>
</div>
Am using jquery.min.js, jquery-1.6.2.js , jquery-ui.min.js.

In the open function, make a logical check whether Thank you message container is visible (assuming that it's visible only if the user has availed the offer) and if it's visible, hide close ('Remind me later' in your case) or else, show it.
Also, you're using a very generic code to manipulate the attributes of dialogue in open. You should make use of the ui variableto make your code specific to only the current dialog
Refer to this thread for both close manipulation and example usage of ui variable
EDIT: making four changes
1) Give an id to the span
NB: This still needs to be specific to this dialog. Please refer to the thread mentioned above.
jQuery('.ui-dialog-titlebar-close').html('<span id=\'reminder\'>Remind me later');
2) Define a boolean variable say availed in your bean and set it in your clickToAvail method
public void clickToAvail(){
// business logic here
this.availed = true;
}
3) Use data and oncomplete
<a4j:commandLink immediate="true" action="#{myBean.clickToAvail}" data="#{myBean.availed}" reRender="renderSuccess" value="Submit" oncomplete="removeReminder(event.data);">
</a4j:commandLink>
4) Define a removeReminder javascript function in the <head> of your page
function removeReminder(availed){
if(availed == 'true' || availed == true)
$('#reminder').hide(); // or remove() decide as per your requirement
}

Related

Microsoft Edge "Leave Site" Message Displays when Choosing from Dropdown

I have an inherited MVC5 web application using Razor that when the page loads, there are two drop downs displayed, some data, and five buttons, one of which is disabled (Save). When I select a different option from the first drop down, what is supposed to happen an input field with a date picker is to display, along with an "OK" button, and the "Save" button is supposed to be enabled. This works fine in IE 11, but in Microsoft Edge, a message appears asking "Leave site? Changes you made may not be saved." If I click the "Leave" button, the spinner appears and I stay on the page.
In IE 11, when any other option is selected from the first dropdown, the spinner appears, the page reloads with the input field with date picker, but OK button appears, and the Save button is enabled. The only time a similar message displays is when the back button is clicked.
I went through the code and found the following:
The code for the first drop down:
#Html.DropDownListFor(m => m.StatusId, new SelectList(Model.StatusList, "Value", "Text", Model.StatusId), new { #class = "form-control", #id = "StatusList"})
I also found a submit button that has been hidden:
#Html.HiddenFor(m => m.CurrentTypeName, htmlAttributes: new { id = "CurrentTypeName" })
<input id="FinalizeValidationButton" type="submit" name="action:FinalizeValidation" style="visibility:hidden" />
In a javascript file I found the following:
//This is the first dropdown mentioned above
$('#StatusList').change(
function () {
triggerFinalizeValidation();
setVisibility();
});
var triggerFinalizeValidation = function () {
var selectedStatus = $('#StatusList').val();
$("#CurrentSignificantActivityTypeName").val($("div.active").prop("id"));
if (selectedStatus != 1) {
navParams.userAction = true;
$('#finalizeButton').prop('disabled', true);
navParams.isDirty = false;
$('#FinalizeValidationButton').trigger('click');
}};
So what's happening is, the user selects a different option from the first dropdown (StatusList), which triggers $('#StatusList').change, which in turn calls triggerFinalizeValidation(), which in turn adds a click event to the hidden submit button ("FinalizeValidationButton"). For whatever reason, it's like it triggers a postback like response, which causes Microsoft Edge to think the user is trying to leave the current page, when they are not.
The hidden button, when clicked, executes the following code in the RiskController.ca. There are a number of dropdowns, fields, etc on the screen other than the fields/buttons that have already been mentioned. So the this part of the code validates what the user has selected and peforms calculations based on what was selected. When I comment out the click event in the JavaScript, the browser message doesn't display, but then the FinalizeValidation method doesn't execute either.
[AcceptVerbs(HttpVerbs.Post)]
[MultiButtonAction(Name = "action", Argument = "FinalizeValidation")]
public ActionResult FinalizeValidation(RiskViewModel viewModel)
{
string currentActivityTypeName = viewModel.CurrentActivityTypeName;
var risk = _riskRepository.FindFull(viewModel.Id);
I'm wondering if there is a way to use #onchange in the dropdown to somehow call the FinalizeValidation method in the controller to see if that resolves the browser message from appearing...Thoughts?
I ended up using
$(window).off('beforeunload');
After
$('#FinalizeValidationButton').trigger('click');
Which resolved the issue.

How to find selected tab on KendoTabStrip on page load?

I am using Kendo UI MVC and i have a kendoTabStrip on acshtml page. By default I am selecting the first tab on page load. All other tabs are loaded dynamically using AJAX.
Issue: I am trying to find the selected tab so i can find its children?
one way to find active tab is by calling select() method without parameter, or anotherway is by checking classname 'k-state-active' however both methods doesnt work
<section class="tpt-tabstrip">
#(Html.Kendo().TabStrip()
.Name("MyTabStrip")
.Animation(false)
.Items(items =>
{
foreach (var revision in Model.MyCollection)
{
items.Add()
.Text(revision.Name)
.LoadContentFrom("MyActionMethod", "MyController", Model.ID);
}
})
)
</section>
<script src="~/Scripts/MyScript.js"></script>
Note that above in cshtml that the script tag is at the end of the page.
Below is the script code
$(function(){
var tabStrip = $("#MyTabStrip").getKendoTabStrip();
if (tabStrip != null && tabStrip.tabGroup.length > 0) {
tabStrip.select(0); // this line is getting executed for sure
}
// the line below returns -1 here why?????
var index = tabStrip.select().index();
// another way to find active tab is by checkikng class name 'k-state-active' however it didnt work either.
// jQuery couldnt find any element with class 'k-state-active'
$('.k-state-active')
})
UPDATE1
The activate event of tabstrip would not work for me because it get fired each time i select tab. I need an event which gets fired only once. Ultimately i want to find NumericTextBox controls on selected tab and attach 'change' event handlers to those controls. like below
$(function(){
var tabStrip = $('#MyTabStrip').data("kendoTabStrip");
tabStrip.bind('activate', function (e) {
$('[data-role="numerictextbox"]').each(function(){
$(this).getKendoNumericTextBox().bind("change",function(e){
alert('changed');
})
})
});
})
here the change event handler will get attach to NumericTextBox everytime i select the tab
$('.k-state-active') works fine it will return the two elements from DOM. You are trying to select element in $(document).ready that's the reason you are not getting element as tab control is not rendered yet.
Try to write your code onActivate event of kendo tab strip control.
OnActivate event is triggered after a tab is being made visible and its animation complete. Before Q2 2014 this event was invoked after tab show, but before the end of the animation. This event is triggered only for tabs with associated content.
See more at http://docs.telerik.com/kendo-ui/api/javascript/ui/tabstrip#events-activate
1st Tab name
<li class="k-item k-state-default k-first k-tab-on-top k-state-active" role="tab" aria-controls="RoleTabs-1" style="" aria-selected="true">
<span class="k-loading k-complete k-progress"></span>
<a class="k-link">Tab Name</a>
2nd Tab Content
<div class="k-content k-state-active" id="RoleTabs-1" style="display: block; height: auto; overflow: auto; opacity: 1;" role="tabpanel" aria-expanded="true">

kendoui menu filter / form

I would like to have a button and when the user clicks on it a filter form pops down just below the button. I would like to utilize Kendo UI controls to achieve the effect.
In fact, what I need is almost exactly the 'filtering' that can be found on this example:
http://demos.telerik.com/kendo-ui/grid/filter-menu-customization
However, I'm not dealing with a grid of data so I can't use that example above.
There are different possible implementations. Here I will describe one based on kendoWindow since then you have a lot of possible customizations for that filtering form.
This is the HTML that includes the button:
<div>
This is the container that includes a
<button id="filter" class="k-button">Filter</button>
that is used to display a form
</div>
And then you define the HTML form. Example:
<div id="form">
<div>Filtering value:<input data-role="autocomplete"/></div>
<button class="k-button">Filter</button>
</div>
Doing the form initialization is:
var form = $("#form").kendoWindow({
title : "Filter",
visible : false,
modal : false,
draggable: false
}).data("kendoWindow");
Where initially we set the form as not visible.
You can define it as modal, draggable or even define the opening and closing effect.
Finally, for opening and placing the form just bellow the button you should:
$("#filter").on("click", function(e) {
// Find clicked button
var button = $(e.currentTarget);
// and get its position
var pos = button.offset();
// shift down the form to open by the height of the button + 5px (margin)
pos.top += button.outerHeight() + 5;
// Apply positioning to the form
form.wrapper.css(pos);
// display form
form.open();
});
You can see this here : http://jsfiddle.net/OnaBai/mpq6k/

How Do I Reselect A KendoUI TabStrip After AJAX Postback in UpdatePanel

Setup
I've got a Telerik Kendo UI TabStrip with multiple tabs inside of an UpdatePanel...
<asp:UpdatePanel ID="DataDetails_Panel" UpdateMode="Conditional" runat="server">
<div id="ABIOptions_TabContainer">
<ul>
<li>Attendance</li>
<li>Grades</li>
<li>Gradebook</li>
<li>PFT</li>
<li>Scheduling</li>
<li>Miscellaneous</li>
<li>Parent Data Changing</li>
</ul>
</div>
</asp:UpdatePanel>
...which I then wire up in javascript later...
var optionTabContainer = $("#ABIOptions_TabContainer").kendoTabStrip({
animation: {
open: {
effects: "fadeIn"
}
},
select: onMainTabSelect
}).data("kendoTabStrip");
Scenario
The users will click on the various tabs and inside of each tab are settings for our portal. When they are in a tab and they make a change to a setting, the expectation is that they'll click on the 'Save' button, which will perform a postback to the server via ajax, because it is in the update panel.
Current Behavior
After the post back happens and the ul content comes back, I reapply the kendoTabStrip setup function call, which makes none of the tabs selected. This appears to the user like the page is now empty, when it just had content.
Desired Result
What I want to do, is after the partial postback happens and the UpdatePanel sends back the ul, I want to reselect the tab that the user previously selected.
What Already Works
I already have a way to preserve the tab that the user clicked on:
var onMainTabSelect = function (e) {
tabToSelect = e.item;
console.log("onTabSelect --> ", e.item.textContent);
}
and a function to reset the selected tab whenever it is called:
function setMainTab() {
if (!jQuery.isEmptyObject(tabToSelect)) {
var tabStrip = $('#ABIOptions_TabContainer').data("kendoTabStrip");
console.log("Attempt to set tab to ", tabToSelect.textContent);
tabStrip.select(tabToSelect);
} else {
console.log("tabToSelect was empty");
}
}
What Doesn't Work
My hypothesis is that the Kendo TabStrip says, "Hey, that tab is already selected" when I call the setMainTab after my postback:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
BindControlEvents();
setMainTab();
});
...and therefore, doesn't set my tab back. If I click on the tab, then Poof, all my content is there just like I expect.
Any ideas what I may be doing wrong?
I ended up changing the onMainTabSelect method to:
var onMainTabSelect = function (e) {
tabToSelect = $(e.item).data("tabindex");
}
which gets me the data-tabindex value for each li in my ul. I couldn't get the tab index from kendo, so I had to role my own. Once I got that value, then I was able to set the selected tab via an index rather than the tab object reference itself.

For a JQuery App with several buttons, should I use <input> buttons, <a> buttons, <button> buttons, or something else?

I need to create a jQuery App with 30 buttons, from 1 to 30, whereby each one calls the exact same action script via Ajax where the parameter that is passed to the action script is simply the number of the button pressed (1 to 30).
For example, let's say the action script is process.php, if button 3 is pressed, then I need to pull data from process.php?btn=3, and if button 27 is pressed, then I need to pull data from process.php?btn=27.
Which type of button should I use for this: <input> buttons, <a> buttons, <button> buttons, or something else? And why do you suggest that?
Also, how would Ajax get the corresponding value (1-30) of the button pressed with the method you suggest?
Thanks!
I would suggest to use <a/> that way if JavaScript is disabled you can maintain the application's functionality.
Button 3
And the script would simply use the href to post to your page.
$("a.actionButton").click(function(e){
e.preventDefault();
$.post(this.href, {}, function(data){
//do something with the data.
});
});
Update
Since JavaScript is required than my recommendation would depend on your application design. If you want the big buttons to look like buttons simply use <input type="button" value="3"/> As by default they will have hover effect, depressed effect built out of the box.
If your buttons do not look like normal buttons maybe just blocks or some other style a <div/> could also be an option. The one downside to using an <a/> would be you always have to suppress the default behavior of the click()
Each will work fine. But the <a> you can style with an image while <input> and <button> you cannot (the browser decides on the look).
Simply bind the click event on the button. Assuming you have this HTML:
Button 1
Button 2
...
Button 3
Here's the Javascript. The trick is to call the AJAX here, and return false to prevent the Browser from changing page.
$('a').click(function(e) {
$.get($(this).attr('href'), function(result) {
alert('AJAX result = '+result);
});
return false;
});
You could create a custom attribute on each button.
<input type="button" onclick="YourCallbackMethod(this)" buttonNumber="1" value="Button 1" />
In your javascript
function YourCallbackMethod(button)
{
var number = $(button).attr("buttonNumber");
// Call the ajax method with the number value.
}
By doing this you can add additional attributes to extend the data stored in each button and it also makes chaning the AJAX target link very easy since it's centralised, rather than spread around multiple anchor tags.
As an alternative to Marks answer, you could use a <form> element, and have each button a submit button; either a input or button. Set the name of the element to "btn" and the value of the element to the button number.
<form id="foo" action="process.php" method="<!-- POST or GET? -->">
<button type="submit" name="btn" value="1">Button 1</button>
</form>
The jQuery would look something like:
jQuery(document).ready(function ($) {
$('#foo').bind('submit', function (evt) {
jQuery.ajax({
url: this.action,
data: $(this).serialize(),
success: function () {
// whatever
}
});
evt.preventDefault();
});
});
If you want the submission to be a POST request, this would most likely be better. For a GET request however, Marks will probably be easier.

Resources