Signal R doesnt update - asp.net-mvc

I have a requirement to show the notification send by administrator.
My menu will be loaded only once.
I also have broadcast notification page where I will send notification to others. On click of save buttom using Hub I am sending the message to the clients.
Here my unread message count (like we have in fb) is placed in the layout .
All my send and receive code is in the Broadcast notification page. Notification count is not getting displayed on the layout menu like (like fb) .
What will be the issue.?
Count is updated on the Webpage where admin will send notification. Other pages say Home page or any other page the notification count which is ther in the layout is not getting updated.
Answer to this will be very helpful for me.
Hub class : on button click i am calling this hub method
public void BroadcastNotifications(string message)
{
// Save data to database
Utility.AddNotification(message);
// Call method to get the number of unread messages (consider the status = read / unread)
int UnreadCount = Utility.getUnreadMessageCount();
UnreadCount = 12;
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<BroadcastMessage>();
context.Clients.All.receiveNotification(message, UnreadCount);
}
Admin page where notification message is going to send .
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Notification</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Message)
</div>
<p>
<input type="button" id="button1" value="Create" />
</p>
</fieldset>
}
#section Scripts
{
<script src="~/Scripts/jquery-1.11.3.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.signalR-1.1.4.js" type="text/javascript"></script>
<script src="~/signalr/hubs"></script>
<script type="text/javascript">
$(function () {
$.connection.hub.logging = true;
var proxy = $.connection.broadcastMessage;
$.connection.hub.start().done(function () {
$('#button1').click(function () {
proxy.server.broadcastNotifications($("#Message").val());
});
});
proxy.client.receiveNotification = function (message, UnreadCount) {
**$("#notification_count").html(UnreadCount);
$("#notification_count").show();**
};
$.connection.hub.start();
});
</script>
}
And the layout page where the notification count should display is
<li class="dropdown" id="notification_li">
<a href="#" class="fa fa-globe fa-inverse dropdown-toggle"
data-canvas="body" style="color:gray;padding-top:17px" data-toggle="dropdown"
role="button" aria-haspopup="true" aria-expanded="false">
<span id="**notification_count**" class="notification_count">0</span></a>
<ul class="dropdown-menu" id="popup">
</ul>
</li>
This is the _layout page where i have to display the count of unread mesasges.
If i trigger the send button the unread count is getting updated on all the admin add notification open pages. But the other pages it remains empty.
Updated _Layout as per the comment
I have moved the signal r client call to _layout
<head>
<meta charset="utf-8">
<title>Services</title>
<!-- Bootstrap core CSS -->
#Styles.Render("~/Content/bootstrapcss")
#Scripts.Render("~/bundles/modernizr")
<script src="~/Scripts/jquery.signalR-1.1.4.js" type="text/javascript"></script>
<script src="~/signalr/hubs"></script>
<script type="text/javascript">
$(function () {
debugger;
$.connection.hub.logging = true;
var proxy = $.connection.broadcastMessage;
proxy.client.receiveNotification = function (message, UnreadCount) {
debugger;
$("#notification_count").html(UnreadCount);
$("#notification_count").show();
};
$.connection.hub.start();
$.connection.hub.start().done(function () {
$('#button1').click(function () {
proxy.server.broadcastNotifications($("#Message").val());
});
});
});
</script>
</head>
<body>
#Html.Partial("_RightMenu")
**#Html.Partial("_TopMenu") **//** Notificationcount span is in this partial view**
<div class="container-fluid body-content">
<div class="row" id="Content">#RenderBody()</div>
<br />
<br />
<footer>
<p>© #DateTime.Now.Year - FOOTER</p>
</footer>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrapjs")
#Scripts.Render("~/Scripts/abcjs")
#RenderSection("scripts", required: false)
</body>
</html>
I have updated as above. In _Layout there are two partial views in which the count i am displaying on one partial view. Is it the correct way to add.
tthis is the signal r file generated automatically
$.hubConnection.prototype.createHubProxies = function () {
var proxies = {};
this.starting(function () {
registerHubProxies(proxies, true);
this._registerSubscribedHubs();
}).disconnected(function () {
registerHubProxies(proxies, false);
});
proxies.broadcastMessage = this.createHubProxy('broadcastMessage');
proxies.broadcastMessage.client = { };
proxies.broadcastMessage.server = {
broadcastNotifications: function (message) {
return proxies.broadcastMessage.invoke.apply(proxies.broadcastMessage, $.merge(["BroadcastNotifications"], $.makeArray(arguments)));
}
};
return proxies;
};
signalR.hub = $.hubConnection("/signalr", { useDefaultPath: false });
$.extend(signalR, signalR.hub.createHubProxies());
}(window.jQuery, window));

I think the problem is the following: You are only receiving notifications on the admins' sites.
I would place the hub script section within the _layout.
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
<script src="~/Scripts/jquery.signalR-2.2.0.js" type="text/javascript"></script>
<script src="~/signalr/hubs"></script>
<script type="text/javascript">
$(function () {
debugger;
$.connection.hub.logging = true;
var proxy = $.connection.broadcastMessage;
proxy.client.receiveNotification = function (message, UnreadCount) {
debugger;
$("#notification_count").html(UnreadCount);
$("#notification_count").show();
};
$.connection.hub.start();
$.connection.hub.start().done(function () {
$('#button1').click(function () {
proxy.server.broadcastNotifications($("#Message").val());
});
});
});
</script>
#RenderSection("scripts", required: false)
<li class="dropdown" id="notification_li">
<a href="#" class="fa fa-globe fa-inverse dropdown-toggle"
data-canvas="body" style="color:gray;padding-top:17px" data-toggle="dropdown"
role="button" aria-haspopup="true" aria-expanded="false">
<span id="notification_count" class="notification_count">0</span>
</a>
<ul class="dropdown-menu" id="popup"></ul>
</li>
You can take a look in a sample project I created for the case:
https://github.com/blfuentes/SignalR_StackOverflow_Question
I updated the nuget packages to the latest version of SignalR 2.2.0

Related

Jquery mobile page id turns into folder name

I made an android app with a multi-page template. When I push the Zoeken button on the home page I go to Page 1 (id = Zoeken). On that page, when I push the button (id = zoek), the app goes to the following url android_asset/www/Zoeken/# instead of going to android_asset/www/index.html#win2 (Page 2)
When I change the id of Page 1, the foldername changes too
Why is the id Zoeken turned into a folder name?
Index.html
<!DOCTYPE HTML>
<html>
<head>
<title>PhoneGap</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="cordova.js"></script>
<link rel="stylesheet" href="jquery.mobile-1.0a1.min.css" />
<script src="jquery-1.4.3.min.js"></script>
<script src="jquery.mobile-1.0a1.min.js"></script>
<script type="text/javascript" src="SQLitePlugin.js"></script>
</head>
<body>
<!-- home -->
<div data-role="page" data-theme="e" id="home">
<div data-role="content">
<img src="img/logo_wablief.png" width="300" height="99" alt="wablief logo">
<ul data-role="listview" data-inset="true">
<li>Zoeken</li>
<li>A tot Z</li>
<li>Info</li>
</ul>
</div>
</div>
<!-- Page 1 -->
<div data-role="page" data-theme="e" id="Zoeken">
<div data-role="header" data-position="inline">
<h1>Zoeken </h1>
</div>
<div data-role="content"> <p>Welk woord wil je zoeken?</p>
<label for="search-basic">Vlaams woord</label>
<input type="search" name="search" id="search-basic" value="" />
Zoek
</div>
</div>
<!-- Page 2 -->
<div data-role="page" id="win2" data-add-back-btn="true" data-theme="e">
<div data-role="header">
<h1>Zoekresultaten</h1>
</div>
<div data-role="content">
</div>
</div>
</body>
</html>
<script>
// Wait for Cordova to load
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
var db = window.sqlitePlugin.openDatabase ("wablief", "", "wablief", 65535);
$("#zoek").bind ("click", function (event)
{
db.transaction (function (transaction)
{
var search = $("#search-basic").val ();
var sql = "SELECT * from wablief WHERE woord LIKE ?";
transaction.executeSql (sql, ["%"+search+"%"],
function (transaction, result)
{
var html = "<ul>";
if (result.rows.length)
{
for (var i = 0; i < result.rows.length; i++)
{
var row = result.rows.item (i);
var woord = row.woord;
var woord2 = row.woord2;
var vertaling = row.vertaling;
html += "<li>" + woord + " " + woord2 + "<br><br>" + vertaling + "</li>";
}
}
else
{
html += "<li> Geen resultaten </li>";
}
html += "</ul>";
$("#win2").unbind ().bind ("pagebeforeshow", function ()
{
var $content = $("#win2 div:jqmData(role=content)");
$content.html (html);
var $ul = $content.find ("ul");
$ul.listview ();
});
$.mobile.changePage ($("#win2"));
}, error);
});
});
function error (transaction, err)
{
alert ("DB error : " + err.message);
return false;
}
}
</script>
I solved the issue bij adding different jQuery and jQuery mobile files.
I am now using the files you can find here:
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
I copied and pasted them, for use offline and now it is working like a charm.

jquery mobile cannot change another the page with data

Index.html
<div data-role="page" id="reviewsPage">
<div data-role="header">
<h1>Reviews</h1>
TWEET
</div>
<script type="text/javascript">
$(document).on("pageshow", "#reviewsPage", function(event) {
$("#mybtn").bind("click", function(e) {
$.mobile.showPageLoadingMsg();
$.mobile.changePage("my.html", {
reloadPage: true, changeHash: true
});
});
});
</script>
</div>
my.html
<script type="text/javascript">
$(document).bind('pagebeforechange', function(event, data) {
$.ajax({
url: " searchresult.php",
success: function(data) {
alert(data);
var markup = "";
$.each(data, function(i, elem) {
var $template = $('<div><li><img class="ui-li-icon profile"><p class="from"></p><p class="tweet"></p></li></div>');
$template.find(".from").append(elem['a']);
markup += $template.html();
});
$("#tweet-list").append(markup).listview("refresh", true);
$.mobile.changePage($("#twitterPage"));
},
error: function(request, error) {
alert(error);
}
});
});
</script>
<div data-role="page" id="twitterPage">
<div data-role="content">
<ul id="tweet-list" data-role="listview" data-inset="true">
<li data-role="list-divider">
<p>Tweetsdd</p>
</li>
</ul>
</div>
</div>
Above code is used to change the page with dynamic data. If i click the link the my.html will not be populated with data. But if i run the my.html file directly it works. If i write two pages inside the same page it works. But i need to run this in separate pages. I have been searching answer for this question since yesterday. I am new to jquery.
Try this
Index.html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script language="text/javascript">
/* VERY IMPORTANT this is before loading jquery.mobile JS */
$( document ).on( "mobileinit", function() {
// Make your jQuery Mobile framework configuration changes here!
$.mobile.allowCrossDomainPages = true;
$.mobile.ajaxEnabled = false;
});
</script>
<script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"> </script>
<script type="text/javascript">
$(document).on("pagebeforeshow", function(event) {
$("#mybtn").bind("click", function(e) {
$.mobile.showPageLoadingMsg();
$.mobile.changePage("my.html", {
reloadPage : false,changeHash : true
});
});
});
</script>
</head>
<body>
<div data-role="page" id="reviewsPage">
<div data-role="header">
<h1>Reviews</h1>
<a href="#" id="mybtn" class="ui-btn-right" data-ajax="false" >TWEET</a>
</div>
</div>
my.html
<div data-role="page" id="twitterPage">
<script type="text/javascript">
$(document).bind('pageshow', function(event, data){
alert("shdgs");
$.ajax({
url : " searchresult.php",
success : function(data) {
alert(data);
var markup = "";
$.each(data, function(i, elem) {
var $template = $('<div><li><img class="ui-li-icon profile"><p class="from"></p><p class="tweet"></p></li></div>');
$template.find(".from").append(elem['a']);
//$template.find(".tweet").append(result.text);
//$template.find(".profile").attr("src", result.profile_image_url);
markup += $template.html();
});
$("#tweet-list").append(markup).listview("refresh", true);
// Transition to the Twitter results page.
$.mobile.changePage($("#twitterPage"));
},
error : function(request, error) {
// This callback function will trigger on unsuccessful action
alert(error);
}
});
});
</script>
<div data-role="content">
<ul id="tweet-list" data-role="listview" data-inset="true">
<li data-role="list-divider">
<p>
Tweetsdd
</p>
</li>
</ul>
</div>
</div>

How to get dynamically created data into a dialog box on listview click

I create a list view dynamically, but i have no clue on how i get the data from the selected list to appear in the dialog box. I have tried several ways but all failed. The only thing i have got going correctly is calling the dialog on click.
I want to display the whole message in the pop up dialog box
my code
<body>
<div data-role="page" id="messages">
<div data-theme="a" data-role="header">
<a data-role="button" href="index.html" data-transition="slide"
data-icon="arrow-l" data-iconpos="left" class="ui-btn-left">
Back
</a>
Refresh
<h3>
Alerts
</h3>
</div>
<div data-role="content">
<script type="text/javascript">
$(document).on("pagebeforeshow", "#messages", function() {
var uid = $.cookies.get( 'uid' );
if(uid == null){
$.mobile.changePage( "account-login.html", { transition: "slide"} );}
$(function(){
$.getJSON("ajaxResponder.php?method=messages",function(data){
var htmlString ="";
$.each(data.messages,function(index,item){
htmlString +='<li data-name='+item.msgid+'><a href="#">'+
'<h3 class="topic">'+item.subject+'</h3>' +
'<p>From: '+item.sender+'</p>' +
'<p>Date: '+item.added+'</p>' +
'<p>'+ item.message +'</p></a></li>' ;
});
$('#list').html(htmlString);
$('#list').listview('refresh');
});
});
});
</script>
<ul id="list" data-role="listview" data-theme="d"></ul>
</div>
<script>
$('#list').on('click', 'li', function() {
$.mobile.changePage("#dialog", {
role: "dialog"
});
});
</script>
</div>
<div data-role="page" data-rel="dialog" id="dialog" data-theme="c" data-close-btn="right">
<div data-role="header" data-position="fixed" data-theme="b">
<h1>New values added!</h1>
</div>
hello
<!-- display item.message here -->
</ul>
</div>
</body>
</html>
updated
Based on your comment, to read any data of the parent element, use .closest().
Just read the text of <a> button and append it to the dialog. I used div #msg for demo purposes.
Demo
$('#list').on('click', 'li a', function () {
var text = $(this).closest('li').attr('data-name');
$('#msg').empty();
$('#msg').append(text);
$.mobile.changePage("#dialog", {
role: "dialog"
});
});

pagebeforeshow event not fired after call to changepage

I'm just starting out in jQM development and have hit a bit of a brick wall.
In short, I have a javascript file and two pages. In the main page (index.html) I'm populating a listview dynamically, and registering the tap event for each and every item for this listview. The on tap event, in return, calls the changepage method to an external page (details.html). This works fine 100% of the time.
In the javascript file, I'm registering for events on pagebeforeshow for the details.html page. This works okay first time out, but any subsequent calls are not triggering the pagebeforeshow event at all. Having had a closer look i can see that the pagechange is being called, pagebeforechange event is being fired okay, but the pagebeforeshow is only fired for that particular item only (untill a complete refresh).
I have set up a sample for you to be able to look at. I would seriously appreciate any feedback given. For all I know - I may be using the wrong events!?
The closest post I could find on SO was Pagebeforeshow not fired on second time change Page event however it doesn't particularly deal with listviews so I'm not sure if it's related or not.
Thanks,
Matt
Index.html
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
<script src="jquery.custom.js" type="text/javascript"></script>
</head>
<body>
<!-- All Stock Search -->
<div id="idxPage" data-role="page" style="height:50px;" data-title="Main Menu">
<div data-role="header" class="sixteen columns">
Home
<h1>
Test
</h1>
</div>
<div data-role="content" style="text-align:center;">
<ul id="ListItems" data-role="listview" data-inset="true" data-filter="true">
</ul>
</div><!-- /content -->
<footer>
<div data-role="footer" data-id="connfooter" class="ui-footer ui-bar-a" role="contentinfo">
<h4 style="text-align: left;" class="ui-title" tabindex="0" role="heading" aria-level="1">
</h4>
</div>
</footer>
</div>
</body>
details.html
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
<script src="jquery.custom.js" type="text/javascript"></script>
</head>
<body>
<!-- All Stock Search -->
<div id="detailsPage" data-role="page" style="height:50px;" data-title="Main Menu">
<div data-role="header" class="sixteen columns">
Home
<h1>
Test
</h1>
</div>
<div data-role="content" style="text-align:center;">
<b>Page placeholder</b>
</div><!-- /content -->
<footer>
<div data-role="footer" data-id="connfooter" class="ui-footer ui-bar-a" role="contentinfo">
<h4 style="text-align: left;" class="ui-title" tabindex="0" role="heading" aria-level="1">
</h4>
</div>
</footer>
</div>
</body>
jquery.custom.js (JS Library)
$(document).on("pagebeforechange", function (event, data) {
alert('changing page...');
});
$(document).on('pageinit', function () {
$("#detailsPage").off();
$("#detailsPage").on("pagebeforeshow", function(event){
alert('about to show page...');
});
$("#ListItems").off();
$("#ListItems").on("listviewbeforefilter", function (e, data) {
var $ul = $(this),
$input = $(data.input),
value = $input.val(),
html = "";
$ul.html("");
if (value && value.length > 2) {
$ul.html("<li><div class='ui-loader'><span class='ui-icon ui-icon-loading'></span></div></li>");
$ul.listview("refresh");
var max = 200;
var limit = 0;
var itemslist = [
{"id":1, "desc":"item1"},
{"id":2, "desc":"item2"},
{"id":3, "desc":"testitm1"},
{"id":4, "desc":"testitm2"}
];
$.each(itemslist, function (i, val) {
if (limit < max) {
if (val.desc.toString().toLowerCase().indexOf(value.toLowerCase()) != -1) {
$ul.append('<li id="' + val.id + '" ><a style="text-align:left" data-icon="arrow-r" data-iconpos="right" >' + val.desc + '</a></li>');
$('#' + val.id).off();
$('#' + val.id).on('tap', function (event) {
var elementId = $(this).attr('id');
$.mobile.changePage("details.html?Id="+elementId, { data: { "Id": elementId} });
});
limit++;
}
}
});
$ul.listview("refresh");
$ul.trigger("updatelayout");
}
});
});
You are incorrectly binding page event.
Instead of this:
$("#detailsPage").off();
$("#detailsPage").on("pagebeforeshow", function(event){
alert('about to show page...');
});
Use this:
$(document).on("pagebeforeshow", "#detailsPage",function(event){
alert('about to show page...');
});
Remember, jQuery Mobile page events must always be added with event delegation.
Also your don't need to use off() with page events, they do not suffer from multiple event binding problem. If you have more question feel free to ask in comments.

How to render data into a jquery mobile page dynamically

I am really new to jQuery Mobile. I am trying to make a simple app with two pages. Page1 is where user will enter search data and Page2 will be where the results are shown. Any help is greatly appreciated.
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<script src="jquery-mobile/jquery-1.7.2.min.js"/>
<script src="jquery-mobile/jquery.mobile-1.0a3.min.js"/>
<link href="jquery-mobile/jquery.mobile-1.0a3.min.css" rel="stylesheet" type="text/css"/>
<script>
$(document).ready(function() {
$('#search').click(function() {
//do some processing and get the data in form of JSON
var data = someotherfunction($("#searchfor").val());
//now lets say I want to pass this data to page2. How to do this?
// I was doing
$('#page1').hide();
$('#page2').show(); // but it removes all the styling from the page.
});
});
</script>
</head>
<body>
<div data-role="page" id="page1">
<div data-role="header">
<h1>Example</h1>
</div>
<div data-role="content">
<input name="searchfor" type="text" id="searchfor"/>
<input type="button" id="search" data-theme="b" value="search"/>
</div>
<div data-role="footer">
<h4>Page Footer</h4>
</div>
</div>
<div data-role="page" id="page2">
<div data-role="header">
<h1>Page Three</h1>
</div>
<div data-role="content">
<p>Your search returned this: {data.value} </p>
</div>
<div data-role="footer">
<h4>Page Footer</h4>
</div>
</div>
</body>
</html>
You might as well make your second page an external page and do the search logic right on it:
$(document).on('click', '#search', function () {
$.mobile.changePage('/path/to/my-script.php?search=' + encodeURIComponent($('#searchfor').val(), { reloadPage : true });
//prevent the default behavior of the click event
return false;
});
Then in your second page you can just receive the $_GET variable, do the search, and output the results.
Otherwise you're looking at using $.ajax() to request a similar response via AJAX:
$(document).on('click', '#search', function () {
$.ajax({
url : '/path/to/my-script.php'
data : { search : $('#searchfor').val() },
dataType : 'json',
success : function (data) {
//assuming that the response in an array of objects (JSON)
var output = [];
for (var i = 0, len = data.length; i < len; i++) {
output.push('<li><h3>' + data[i].name + '</h3><p>' + data[i].description + '</p></li>');
}
var $page = $('#page2').children('.ui-content').append('<ul data-role="listview">' + output.join('') + '</ul>');
$.mobile.changePage($page);
},
error : function (jqXHR, textStatus, errorThrown) { /*don't forget to handle errors*/ }
});
});

Resources