How to Customize Hyperlinks on Client Side in ASP.NET MVC - c#

I need to be able to do two things with Javascript or JQuery, without involving third-party open source libraries:
Use a jQuery or Javascript function to fill the HREF attribute of a link.
Perform an HTTP Get or Post operation OnUpdate of a text box or combo box (using the above javascript function to specify the HTTP target)
The end result will be hyperlinks posted to the controller that look similar to this:
http://mydomain/addresses/1?order=name&state=ca
The controller will return a new page, ordered by name and filtered on the state of California.
Suggestions?

If you have 2 textboxes and a hyperlink with url, try something like:
$(document).ready(function() {
$('a#yourHyperLinkId').click(function(event) {
event.preventDefault();
var url = $(this).attr('href');
var order = $('input#order').val();
var state = $('input#state').val();
$.get(url, { order: order, state: state }, function(response) {
$('div#yourDivForResponse').html(response);
});
});
});

I am not sure I follow...
Why do you need to fill the HREF of the link if your going to use JQuery to do the postback anyway?

Some elements of answer here : Passing Javascript variable to <a href >
If you want to load the controller response in the window, you can use a form with a crafted action. If not, you can either use an iframe as a target to the form or use an XHR object. Whatever solution you choose, you will link it to the onchange event of the text box or combo box.

Thanks fellas for pointing me in the right direction.
Answer to #1:
document.getElementById("link2").setAttribute("href",strLink);
Answer to #2 (more or less):
$("#mySelect").change(function() {
document.location = this.value;
});

Related

Lazy loading Telerik window content

I am working in ASP.NET MVC 3 and using Telerik. I have an empty telerik window. My goal is to only ask server for content when the user clicks a button, however I have no idea how this could be done. I imagine that to accomplish this I would need to store a reference to the telerik window in question. But how do i do this? plz help. This is how far I have got:
#{
Html.Telerik().Window()
.Name("ImportDialog")
.ClientEvents(events => events.OnOpen("DialogOpen"))
.Visible(false)
.Title("Import users")
.Draggable(false)
.Resizable(resizing => resizing.Enabled(false))
.Modal(true)
.Width(400)
.Height(400)
.Render();
}
I do want do do somethin in DialogOpen function, or alternatevly replace that client side function with a server side funciton....
You should use the client API of the Telerik Window and more specifically the ajaxRequest method.
So for example when the button is clicked you should get the client object and call the ajaxRequest method which will make the Window retrieve its content from that MVC action method.
e.g.
function DialogOpen(){
var myWin= $('#ImportDialog').data('tWindow');
myWin.ajaxRequest("Controller/Action", { name: "John",location:"Boston"});
}
I found one type of answer, however i am not sure yet if it is the best.
In the javascript function DialogOpen I send an ajax request to an url(also known as an Action of a Controller in MVC), the I put the result in the content of the dialog window, like so:
function DialogOpen ()
{
$.ajax({
type: "POST",
url: "Controller/Action",
data: "name=John&location=Boston",
success: function (htmlContent)
{
$('#ImportDialogContent').html(htmlContent);
},
error: function ()
{
$('#ImportDialogContent').html("<p>Could not import user data at this time</p>");
}
});
}
P.S.: I gave an ID to content area of telerik Window(ImportDialogContent)!

Jquery popup on mouse over of calendar control

I am using the Calendar control of ASP.NET. I need to display a pop-up form when I hover over a particular date in the Calendar control. This pop-up should display data from database.
Does anyone have a solution for this?
You should have an empty div:
<div id="popup"></div>
then bind an event to the calendar elements:
('li.calendar').hover(function(){
//make an ajax call and populate the popup div with the data
//easiest method is jquery.load(), but if you need more control use jquery.ajax();
$("popup").load('path/to/page.asp',data,function(){
$("popup").show();
});
});
Look at jquery.load() and jquery.ajax()
I dont know how asp name the date spans, check it, its very easy to detect
after getting the selector
user jQuery to add the event
jQuery('selector').hover(function(){ //or use mousemove
getPopup(jQuery(this).text()); // just send any data to detect the date
}) ;
after that you'll need to make an AJAX request in the getPopup function
you may use
jQuery.get()//or jQuery.post()
__doPostBack()//if you have update panels
//or any ajax technique xmlhttprequest,PM,...
in the response of the ajax request just draw the popup ...
hope this helps
examle getPopup function
function getPopup(date/*for example*/){
jQuery.getScript('www.myWebsite.com/pageThatDrawsThePopup?date='+date);
// getScript assuming that the return value is JS code the immediately draws the popup
// ?date = date assuming that your page takes the date as query string and get the data from the database upon this field
//dont forget to change the url
//very simple very easy ...
}
Add a CSS class to the cell containing the date that should trigger the popup. You'll need to override the DayRender event to do this.
void myCalendar_DayRender(object sender, DayRenderEventArgs e)
{
if (e.Day.Date.Day.ToString().EndsWith("7")){// Replace with your own condition
e.Cell.CssClass+= "specialCell"; //replace with your own custom css class name
}
}
Then add some JavaScript (or Jquery) to trigger the pop-up. The JQuery ajax functions provide the easiest way to get your data and populate the pop-up as per #user1225246's answer.
$(document).ready(function(){
$('.specialCell').hover(function(){
function(){//This will get called when you mouseover
alert('put your JQuery AJAX code here.');
},
function(){
alert('do any clean-up (e.g. hiding the popup if you need to) here.');
}
});

Modal editing in MVC

I've been searching for a way to update data using a modal pop-up.
Right now I'm using devexpress, because we're already using other devexpress controls (but this could change if a jquery library would be easier!!)
I'm stuck with the validation aspect. Frankly, the entire process seems quite hard for what I'm trying to achieve.
Anyways, let me describe the process that I've currently worked out:
-The Index page contains an overview of the different elements that can be updated. Using a HtmlExtension, I was able to create a devexpress popup which loads the edit page when you open the popup. => #Html.PopupControl().WithText("Edit").PopupGoesTo(Url.Action("EditPopup", etc etc)
-The edit page -which is just a partial view- works just fine.
I've created a little test page, which contains 1 textbox, which takes in a decimal.
I want to submit the form using ajax (because frankly, I have no idea how I can show the validation if I do a full post back, since I need to be able to create the popup and bind the data to it AND trigger the validation errors).
<script type="text/javascript">
function EndPopUpUpdate(message) {
if (message.url) {
window.locatin.href = url;
}
$("#submitButtonPopUp, #loadingPopUp").toggle();
}
function BeginPopUpUpdate() {
$("#submitButtonPopUp, #loadingPopUp").toggle();
}
</script>
using (Ajax.BeginForm("Edit", "xxx", new AjaxOptions { UpdateTargetId = "PopUpDiv", HttpMethod = "Post", OnBegin = "BeginPopUpUpdate", OnComplete = "EndPopUpUpdate"}, new { id = "PopUpForm" }))
{
<div id="PopUpDiv">
#Html.Partial("EditPopup", new xxxViewModel())
</div>
}
I was able to achieve validation when I postback by manually rehooking the jquery events (because these don't get hooked since the page gets loaded dynamicly)
function ReconnectValidation() {
$("#PopUpForm").ready(function () {
$.validator.unobtrusive.parse("#PopUpForm");
});
$("#submitButton").click(function (e) {
var form = $("#PopUpForm");
if (!form.valid()) {
e.preventDefault();
}
});
}
So this handles my client side validation, which works.
Now, my actual problem! Server side validation.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([ModelBinder(typeof(CommandModelBinder))] UpdateCommand command)
{
if (!ModelState.IsValid)
{
//using the command pattern
var handlerResult = HandlerLocator.GetQueryHandler<IGetOverviewHandler>().Execute(..);
return PartialView("EditPopUp", handlerResult.ViewModel);
}
HandlerLocator.GetCommandHandler<UpdateCommand>().Handle(command);
var returnLink = Url.Action("Index", new {..});
return Json(new { url = returnLink }, JsonRequestBehavior.AllowGet);
}
I've written a CustomModelBinder, which does nothing but look for the properties in my command object (my return model if you will) and looks in the formcollection if it can find a matching object with the same name. Then it tries to convert it and it binds a ModelError to my ModelState if it fails.
So, now we have a ModelState which is either valid or is invalid.
If it's valid, I want to redirect to the Index (so my overview can update). I've read that I should handle this in the client side, because the ajax.BeginForm is going to replace the
"PopUpDiv"-div with the result (which just creates the same page within my page).
Here is the onComplete event:
function EndPopUpUpdate(message) {
if (message.url) {
window.locatin.href = url;
}
$("#submitButtonPopUp, #loadingPopUp").toggle();
}
The problem is, that I don't receive a json message, but I receive a PartialView. This means I can't access the message.url..because that's not what I recieve :/
So that is problemo number 1
If the object is not valid, I want to return a partialview with the model and give an error to the user. When I return the partialview, it just replaces the current view but it doesn't show any validation errors..
That is problem number 2 :)
Also, if you know a better way to solve this problem, please don't hesitate to respond (because this method just seems really convoluted for what it does -or should do-)
Sorry for the lengthy post, but I hope everything is clear.
Thanks for your help & time!
I've used the dialog plugin from jQuery UI () before, which I've found works well. I normally get the links to open up in an iframe within the popup, which avoids the problem you describe where the jQuery validation events don't get hooked up because the page gets loaded dynamically - both client side and server side validation should work as normal, just within this iframe.
The nice thing about this technique is that you can generate action links as normal within your index page, just add a class of popup to them e.g.
#Html.ActionLink("Edit", "Edit", new { id = Model.Id }, new { #class = "popup" })
Then, you can get these links to open in a dialog iframe with jQuery like:
$("a.popup").click(function(e) {
e.preventDefault();
$("<iframe />").attr("src", $(this).attr("href") + "?popup=true").dialog({ show: "fadeIn", modal: true, width: 300, height: 300});
});
This basically looks for popup links, cancels the default behaviour (page navigation) and opens that URL in a iframe within a popup, adding a querystring to identify that the page is within a popup. The reason for this querystring and knowing its a popup allows you to load a different layout page within the view, maybe through an action filter e.g.:
public class Popup : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result != null
&& filterContext.Result is ViewResult
&& filterContext.RequestContext.HttpContext.Request["popup"] == "true")
(filterContext.Result as ViewResult).MasterName = "~/Views/Shared/_PopupLayout.cshtml";
}
}
This means you can easily apply this attribute to classes where you want action methods to apply. This method also means if you change your mind about the implementation in the future (ie removing the popups) then you can easily remove the jQuery that cancels the clicks and your app will continue to function as a normal MVC app with separate pages, and all the navigation/validation etc will 'just work'.
I hope that all makes sense and helps.

Jquery class and its function

I am developing discussion panel in asp.net in which I am drawing some spans through javascripts
$("#commenttr").after("<tr id="+i+"><td class=\"labelPortion\"></td><td class=\"controlPortion\">" +out[i]+ "</td><td><span style = \"cursor:pointer\" class = \"plblAgreeComment\" id = \"" + ids[i+1] + "\"> Vote Up </span> <span style = \"cursor:pointer\" class = \"plblDisAgreeComment\" id = \"" + ids[i+1] +"\">Vote Down </span><span id = \"ptxtAgreeComment\" >"+ agrees[i+1] + " </span></td></tr>");
But when I am calling the jquery function
$(".plblAgreeComment").click(function(){
alert("hi");
}
Its not working. Please help me.
Description
You need jQuery .live() or .on() method to bind events to dynamically created html.
Choose .live() or .on() depending on the version of jQuery you are using.
.live() Available since jQuery 1.3. Attach an event handler for all elements which match the current selector, now and in the future.
.on() Available since jQuery 1.7. Attach an event handler function for one or more events to the selected elements.
Sample
$(".plblAgreeComment").live('click', function(){
alert("hi");
});
$(".plblAgreeComment").on('click', function(){
alert("hi");
});
More Information
jQuery.live()
jQuery.on()
Update: jsFiddle Demonstration
Use jQuery on since you are adding these items to your DOM dynamically
$(function(){
$("body").on("click",".plblAgreeComment",click(function(){
alert("hi");
});
});
on will work for current elements and future elements.
http://api.jquery.com/on/
on is available from jQuery 1.7 onwards, If you are using an older version of jQuery, you should check live http://api.jquery.com/live/
Try using .on in below syntax,
$(document).on('click', '.plblAgreeComment', function(){
alert("hi");
});
In the above code, use the table selector instead of document select.
two things.. you might have an extra character in class name when generating the html for your row.
class = \"plblAgreeCom
maybe should be:
class =\"plblAgreeCom
or you're attaching click handler before the DOM is being modified in which case:
$(".plblAgreeComment").click(function(){
alert("hi");
}
should be:
$(".plblAgreeComment").live("click", function(){
alert("hi");
}
If you want to bind events to dynamically injected DOM elements, you need to use the on method so that any new elements are bound to that event listener:
$(".plblAgreeComment").on("click", function(){
alert("hi");
}
Note: there are other methods, such as live() that will achieve similar effects, but they are being deprecated in favor of on, which handles this situation for every scenario.

How can i change image path on click for asp.net dynamic content

I am using jquery for changing image path but its not working for asp.net dynamic content
The jquery function is
$('img.selection').click(function () {
this.src = 'images/selected_img.png';
});
This function is not post backing in to the C#, so am not getting changed image values.
Please help me...
try this :
$(this).attr("src", 'images/selected_img.png');
The problem might lie in that asp controls id's are changed when sent to the client.
If this is the case you can fix this in to ways
Set the controlidmode to static on your control in asp.
get the id of the control with jQuery with selectors: $('[id$=theidnameofthecontrol]').click(function () ....
Also you do not need postback. If you provide the new url with jQuery, it should load this without having to postback.

Categories