I'm using Web Essentials 2012 and Visual Studio 2012 and Razor Web Pages (not MVC).
I have a jquery ajax that looks like this:
$("#test1").ready(function () {
var test = { "loadTestList": "loadTestList" };
function loadTestList(response) {
var ddlTest = $('#test1');
ddlTest.empty();
ddlTest.append(
$("<option></option>").text('All').val('All')
);
for (var i = 0; i < response.length; ++i) {
ddlTest.append(
$("<option></option>").text(response[i].TestName).val(response[i].TestName)
);
}
}
$.ajax({
url: "../Controllers/TestController.cshtml",
data: test,
type: "POST",
dataType: "json",
success: function (response) {
loadTestList(response);
},
error: function () {
console.log("Sorry, there seems to be a problem contacting the Test server.");
console.log(response.responseStatus);
console.log(response.responseText);
}
});
});
This actually works.
Now I have my controller has code like this:
#* Controllers/TestController.cshtml *#
#{
if (IsPost && Request["loadTestList"] != null)
{
var tests = new TestRepository(new TestContext());
var testslist = tests.Load();
Json.Write(testslist, Response.Output);
}
}#
And yes, this works too.
But when I do this:
#{
<!-- #region TestMe -->
if (IsPost && Request["loadTestList"] != null)
{
var tests = new TestRepository(new TestContext());
var testslist = tests.Load();
Json.Write(testslist, Response.Output);
}
<!-- #endregion -->
}#
This breaks jQuery every time. $.ajax goes to error everytime.
So does anyone know a way to prevent this from happening? I really like regions, but I can't have it breaking the rest of jQuery.
Also why would this break jQuery in the first place if all I'm passing (through Json.Write) is testslist?
NOTE: TestController.cshtml has only server side code. No HTML at all.
Inside #{ } block you can use standard c# precompiler directive:
#region [region_name]
#endregion
Inside
<script></script>
block use web essentials pattern for javaScript:
//#region [region_name]
//#endregion
Related
My DiaryHub.vb has the following:
Imports Microsoft.AspNet.SignalR
Imports Microsoft.AspNet.SignalR.Hubs
Namespace UIS
<HubName("DiaryHub")>
Public Class DiaryHub
Inherits Hub
Public Sub PostDiaryHeadline()
' Call the addNewMessageToPage method to update clients.
Clients.All.addNewDiaryHeadlineToPage()
End Sub
End Class
End Namespace
My Home/Index window has the following code to initiate/configure SignalR.
$(function () {
// Save the reference to the SignalR hub
var dHub = $.connection.DiaryHub;
// Invoke the function to be called back from the server
// when changes are detected
// Create a function that the hub can call back to display new diary Headline entry.
dHub.client.addNewDiaryHeadlineToPage = function () {
// refresh the Headline Entries to the page.
outputHLDiaryEntries();
};
// Start the SignalR client-side listener
$.connection.hub.start().done(function () {
// Do here any initialization work you may need
outputHLDiaryEntries();
});
})
The code works and on launch the Headline diary entries are displayed.
I also have a button that opens a Kendo window as a modal with a form for adding new diary entries using this function:
function openAddWindow() {
var addWindow = $("#window").data("kendoWindow");
addWindow.refresh({
url: "Home/AddDiaryEntry/"
});
addWindow.open();
addWindow.center();
}
I then have the following Javascript in my AddDiaryEntry page:
function createDiaryEntry() {
var validFlag = true;
var errorMsg = "";
//Validate New Diary Entry
// removed for brevity...
if (validFlag) {
//data is valid
//get value of checkbox
var cbValue = ($("#addNew_dHeadline").is(':checked')) ? true : false;
//clear error area
$('#errorArea').html("");
var response = ''
$.ajax({
url: 'Home/SaveDiaryEntry',
type: 'POST',
data: {
dDate: $("#addNew_dDate").text(),
dCreatedBy: $("#addNew_dCreatedBy").text(),
dName: '#AppShort',
dTeam: teamValue.value(),
dType: typeValue.value(),
dRef: $("#addNew_dREF").val(),
dHeadline: cbValue,
dServer: multiSelect.value(),
dComment: editor.value()
},
success: function (result) {
response = result;
alert(response);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
response = "err--" + XMLHttpRequest.status + " -- " + XMLHttpRequest.statusText + " -- " + errorThrown;
alert(response);
}
});
//close window
var addWindow = $("#window").data("kendoWindow");
addWindow.close();
//if headline entry call SignalR post function to refresh diary entries
if (cbValue) {
// reference to the SignalR hub
var dHub = $.connection.DiaryHub;
// function to update all clients
dHub.client.PostDiaryHeadline(); //THIS IS A FUNCTION IN DiaryHub.vb
}
} else {
//error in data
var out = '<ul class="error">' + errorMsg + '</ul>';
// display errors
$('#errorArea').html(out);
}
}
The code works fine - validates the data, saves data to database. The issue I'm having is when I try to call dHub.client.PostDiaryHeadline() to invoke the SignalR function. I get the error: JavaScript runtime error: Object doesn't support property or method 'PostDiaryHeadline'
How do I call the function? Should I call the function before I close the modal window?
From what I can see your actually expecting a response rather than a server call.
adding server will fire a request.
if (cbValue) {
// reference to the SignalR hub
var dHub = $.connection.DiaryHub;
// function to update all clients
dHub.server.PostDiaryHeadline(); //THIS IS A FUNCTION IN DiaryHub.vb
}
Your already receiving the response here:
dHub.client.addNewDiaryHeadlineToPage = function () {
// refresh the Headline Entries to the page.
outputHLDiaryEntries();
};
//EDIT
There seems to be slight issues through out, so apart from the above(which needs fixing).
On the hub name (backend) replace with: <HubName("diaryHub")>
In your JS replace with: var dHub = $.connection.diaryHub;
Finally in your createDiaryEntry(); body should look like so:
$.connection.hub.start().done(function () {
// Do here any initialization work you may need
if (cbValue) {
// reference to the SignalR hub
var dHub = $.connection.diaryHub;
// function to update all clients
dHub.server.postDiaryHeadline(); //THIS IS A FUNCTION IN DiaryHub.vb
}
});
There are a few SignalR issues but that should get you on the right path.
Most SignalR issues stem from case sensitivity and structuring. All very common.
Should be the last issue, replace with: dHub.server.postDiaryHeadline();
lower case "p"
Here is my code, I have included following .js files, onpage load it is giving error "ReferenceError: CryptoJS is not defined" why does it give that error when already js references are added. I am making a sharepoint-2013 app using office 365.
<script type="text/javascript" src="../Scripts/sha1.js"></script>
<script type="text/javascript" src="../Scripts/hmac-sha1.js"></script>
'use strict';
var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
(function () {
// This code runs when the DOM is ready and creates a context object which is
// needed to use the SharePoint object model
$(document).ready(function ()
{
getUserName();
$("#button1").click(function()
{
paraupdate();
});
});
// This function prepares, loads, and then executes a SharePoint query to get
// the current users information
function paraupdate()
{
var str=""+$("#textbox1").val();
alert(""+str);
var message = str+"json539ff0f815ca697c681fe01d32ba52e3";
var secret = "<my private key>";
var crypto = CryptoJS.HmacSHA1(message, secret).toString();
alert("crypto answer is " + crypto);
var siteurl="http://pnrbuddy.com/api/station_by_code/code/"+str+"/format/json/pbapikey/539ff0f815ca697c681fe01d32ba52e3/pbapisign/"+crypto;
$.ajax({
url: siteurl,
type: "GET",
dataType: 'json',
success: function (data) {
alert("IN Success");
alert(""+data.station_by_code);
},
error: function (error) {
alert("IN Error");
alert(JSON.stringify(error));
}
});
}
function getUserName()
{
context.load(user);
context.executeQueryAsync(onGetUserNameSuccess, onGetUserNameFail);
}
// This function is executed if the above call is successful
// It replaces the contents of the 'message' element with the user name
function onGetUserNameSuccess()
{
$("#label1").html("Enter Station Code : ");
$("#button1").val("CLICK");
}
// This function is executed if the above call fails
function onGetUserNameFail(sender, args) {
alert('Failed to get user name. Error:' + args.get_message());
}
})();
include core-min.js before sha256.js
There are one of two forms for fixing this:
1: Manual Load, i have more success with this pattern:
$.getScript(scriptbase + "SP.Runtime.js",
function () {
$.getScript(scriptbase + "SP.js", execOperation);
}
);
Example:
$.getScript("~hostUrl/_layouts/15/SP.RequestExecutor.js", getListDataREST);
2: Script on Demand:
SP.SOD.executeFunc('sp.userprofiles.js', 'SP.ClientContext', loadUserData);
This SharepointExchange posting, gives the usual JSOM implementation for most AppParts: Jquery is not firing on Page load SharePoint 2013
Error solved I added online references instead,
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha1.js"></script>
Maybe is too late, but:
var CryptoJS = require('crypto-js');
var hash = CryptoJS.HmacSHA256("Message", "secret");
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
console.log(hashInBase64); // qnR8UCqJggD55PohusaBNviGoOJ67HC6Btry4qXLVZc=
Works fine in node.js.
\\code
public ActionResult mapPartial(DataTable dt)
{
string strEvents = "[";
foreach (DataRow row in dt.Rows)
{
strEvents += "[" + row["Lat"].ToString() + ", " + row["Long"].ToString() + ", " + "\"" +
row["LastName"].ToString() + row["DateOfBirth"].ToString() + "\"" + "],";
}
strEvents = strEvents.Remove(strEvents.LastIndexOf(","));
strEvents += "]";
ViewBag.locpoints = strEvents;
return PartialView(dt);
}
//in the partial view page
<script type="text/javascript">
function mapInit(Viewbag.locpoints) {
var arr = $.parseJSON(Viewbag.locpoints);
//more code which assigns a map to div map below
}
</script>
<div id="map" class="map"></div>
How can i call the JS function immediately to render my map when the partial view is loaded. The partial method in the controller returns a string which is used as parameter in the JS function. Hope it makes sense.
Since you appear to be using JQuery why not:
<script type="text/javascript">
$(document).ready(function(){
var arr = $.parseJSON("#Viewbag.locpoints");
//more code which assigns a map to div map below
});
</script>
I also changed how you referenced your ViewBag value since the way you have it, it won't be be a string literal in JavaScript.
Also, as a side note consider using JSON serializer to convert your data into JSON. It is considered a bad practice to do it manually like you did above.
After you define it, you just call it. However, it looks like you are including the MVC Viewbag values in the JS function definition. You should be passing those values when you call the JS method:
<script type="text/javascript">
function mapInit(locPoints) {
var arr = $.parseJSON(locPoints);
//more code which assigns a map to div map below
}
mapInit(#(Viewbag.locpoints));
</script>
Note: This assumes you have jQuery loaded.
Consider using the onSuccess Ajax Option and wire up a javascript function where your jquery is written. For example you have following script written in your mainView that calls the partial View. Suppose you want do something when the anchor tag in your partial view is clicked
var fromPartial=function()
{
var v = $(this).closest("div");
var mId = v.attr('id');
if (mId == 'divDetail') {
event.preventDefault();
//what you want to achieve
}
}
Now in your partial view the anchor tag is created as shown below
#Ajax.ActionLink("Select", "AssignSpeaker", new {
conferenceId = ViewBag.ConferenceId, sessionId = session.Id },
new AjaxOptions() { HttpMethod="Get",
InsertionMode= InsertionMode.Replace, UpdateTargetId="yourTarget",
OnSuccess="fromPartial" })
We have implemented a much simpler solution.
_Layout.cshtml after #RenderSection("scripts", required: false) (and Jquery,etc.)
<script>
$(document).ready(function () { if (typeof partialScript !== "undefined") partialScript();});
</script>
Then, in your partial view:
<script type="text/javascript">
function partialScript() {
alert("hi");
}
</script>
This ensures the following:
jQuery is loaded
All main view scripts are loaded
DOM is ready
Try to call your controller via JQuery.
$(document).ready(function () {
$.ajax({
type: 'GET',
url: 'your_controller_url',
success: function (data) {
//Do your stuffs here
}
});
}
The only way you can do this is by calling your controller action using JQuery and have it return your partial view. Use Jquery to update whatever section of the page the partial view goes to and then call the javascript method you want to render the map
I have the following code in my main Dancer app .pm:
package Deadlands;
use Dancer ':syntax';
use Dice;
our $VERSION = '0.1';
get '/' => sub {
my ($dieQty, $dieType, $bonus);
my $button = param('button');
$dieQty = param('dieQty');
$dieType = param('dieType');
$bonus = param('bonus');
if (defined $dieQty && defined $dieType) {
return Dice::Dice->new(dieType => $dieType, dieQty => $dieQty, bonus => $bonus)->getStandardResult();
}
template 'index';
};
true;
Here is my JavaScript:
$(document).ready(function() {
$('#standardRoll').click(function() {
$.get("/lib/Deadlands.pm", { button: '1', dieType: $("#dieType").val(), dieQty: $("#dieQty").val(), bonus: $("#bonus").val() }, processData);
function processData(data) {
$("#result").html(data);
}
});
});
I have a div in my web page called result that I want to be updated with the die roll result from Perl. Dancer keeps coming back with a 404 error in the command window when I push the submit button.
/lib/Deadlands.pm needs to be the URL of your route (probably / in this case), not the filesystem path of your Perl module.
Your AJAX request needs to point to a URL that actually exists, not a filename that has nothing to do with the web. Looks like $.get('/', ...) would do in this case.
I keep getting this error in my JavaScript no matter what fix I try. It's almost as if $.connection is not being recognized even though I have all the SignalR JavaScript libraries in place in my _layout. I get the following error in the Chrome browser console:Uncaught TypeError: "Cannot read property 'multipleFileHub' of undefined Index:508
(anonymous function) Index:508
x.event.dispatch jquery-2.0.2.js:4692
y.handle jquery-2.0.2.js:4376" of undefined".
Does it matter that my Global.asax inherits from "StsMvcHttpApplication" rather than the standard "System.Web.HttpApplication"? And in my case, I have to put the "RouteTable.Routes.MapHubs();" in my "RegisterRoutes" method rather than "Application_Start" since Application_Start doesn't fire fast enough... it starts hunting for controllers if I put it in the app start.
Would appreciate the help! I'll show the layout code first and then all the separate pieces of code:
_LAYOUT
#section head
{
#Scripts.Render("~/Scripts/Libs/jquery-2.0.2.min.js")
#Scripts.Render("~/Scripts/Libs/jquery-ui-1.10.3.min.js")
#Scripts.Render("~/Scripts/Libs/jquery.validate.min.js")
#Scripts.Render("~/Scripts/Libs/jquery.validate.unobtrusive.min.js")
#Scripts.Render("~/Scripts/Libs/modernizr-2.6.2.js")
#Scripts.Render("~/Scripts/Libs/modernizr.custom.blobconstructor.js")
#Scripts.Render("~/Scripts/SidebarMenu.js")
#Scripts.Render("~/Scripts/BC_Common.js")
#Scripts.Render("~/Scripts/scene.layoutservice.js")
#Scripts.Render("~/Scripts/scene.dataservice.js")
#Scripts.Render("~/Scripts/jquery.signalR-1.1.2.min.js")
#Scripts.Render("~/signalr/hubs")
#Scripts.Render("~/Scripts/scene.startup.js")
}
INDEX.CSHTML
$('#dBtn').click(function () {
var docIds = sceneLayoutService.getSelection();
if (docIds.length === 0) {
alert("you need to select one");
return false;
} else {
var docIdsParam = jQuery.param(docIds.map(function (value) {
return { "name": "docIds", "value": value };
}));
// Proxy created on the fly
var test_connection = $.connection.multipleFileHub;
// Start the connection
$.connection.hub.start().done(function() {
test_connection.server.send("test");
});
}
return true;
});
SERVER CODE:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
namespace Portal.Web.Hubs
{
[HubName("multipleFileHub")]
public class multipleFileHub : Hub
{
public void Send(string message)
{
// Call the addMessage method on all clients
Clients.All.addMessage(message);
}
}
}
GLOBAL.ASAX ROUTING
public static void RegisterRoutes(RouteCollection routes)
{
RouteTable.Routes.MapHubs();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?favicon.ico(/.*)?" });
routes.Ignore("{*allpng}", new { allpng = #".*\.png(/.*)?" });
routes.Ignore("{*allgif}", new { allgif = #".*\.gif(/.*)?" });
routes.Ignore("{*alljpg}", new { alljpg = #".*\.jpg(/.*)?" });
routes.MapRoute(
"Error", // Route name
"Error/{action}/{id}", // URL with parameters
new {controller = "Error", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Landing", id = UrlParameter.Optional } // Parameter defaults
);
}
ALL JAVASCRIPT REFERENCES ON THE PAGE
<script src="/ConnectPortal/Scripts/Libs/jquery-2.0.2.min.js"></script>
<script src="/ConnectPortal/Scripts/Libs/jquery-ui-1.10.3.min.js"></script>
<script src="/ConnectPortal/Scripts/Libs/jquery.validate.min.js"></script>
<script src="/ConnectPortal/Scripts/Libs/jquery.validate.unobtrusive.min.js"></script>
<script src="/ConnectPortal/Scripts/Libs/modernizr-2.6.2.js"></script>
<script src="/ConnectPortal/Scripts/Libs/modernizr.custom.blobconstructor.js"></script>
<script src="/ConnectPortal/Scripts/SidebarMenu.js"></script>
<script src="/ConnectPortal/Scripts/BC_Common.js"></script>
<script src="/ConnectPortal/Scripts/scene.layoutservice.js"></script>
<script src="/ConnectPortal/Scripts/scene.dataservice.js"></script>
<script src="/ConnectPortal/Scripts/jquery.signalR-1.1.2.min.js"></script>
<script src="/ConnectPortal/signalr/hubs"></script>
<script src="/ConnectPortal/Scripts/scene.startup.js"></script>
It turns out the cause of this issue was because the jquery library was being loaded on the page a second time. There was another javascript library being used in the layout that was inserting the non-minified jquery library on the page after the first minified one. It was hard to find this since the code to insert the other jquery library was not displayed on the layout page. Anyway, just thought I'd let all who read this know that the issue is DEFINITELY related to the jquery library being added after the signalR library.
David Fowler, from the above comments, was spot on! Thanks!