I'm trying to create some html elements as a reponse to a button click in my visualforce page, and i am using javascript remoting, but no matter what i do the page keeps refreshing after the button click.
my visualforce page:
<apex:page Controller="BpmIcountPayment">
<head>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css"/>
</head>
<body>
<script>
function addProductRow(e) {
e.preventDefault();
var productId = $('select[id$=productsLov]').val();
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.BpmIcountPayment.getProductRowData}',
productId,
function(result, event) {
if (event.status) {
productRowHtml = '<div id="p-' + result.Id + '">';
productRowHtml += '<span>' + result.Description + '<span>';
productRowHtml += '<button class="plusButton">+</button><input type="number">1</input><button class="minusButton">-</button>';
if (result.Name == 'discount') {
productRowHtml += '<input classtype="number"></input><span>₪</span>';
};
productRowHtml += '<span>' + result.Price + '₪</span>';
$('div[id$=productRows]').append(productRowHtml);
} else if (event.type === 'exception') {
console.log(event.message + ' ' + event.where);
} else {
console.log('else ' + event.message);
}
}, {escape: true});
}
</script>
</body>
<apex:form >
<div>
<apex:selectList id="productsLov" value="{!productsTitle}" multiselect="false" size="1">
<apex:selectOptions value="{!ProductsLov}"></apex:selectOptions>
</apex:selectList>
<button id="addProductButton" onclick="addProductRow()" reRender="false">add product</button>
</div>
<div id="productsRows">
</div>
</apex:form>
</apex:page>
I even managed to print the result into the console, but it does so after refreshing the page.
my controller:
public class BpmIcountPayment{
private final Account account;
public String productsTitle {
get { return 'products'; }
set;
}
public List<Product2> productsList {
get { return productsList; }
set { productsList = value; }
}
public BpmIcountPayment() {
account = [SELECT Id, Name, Site FROM Account
WHERE Id = :ApexPages.currentPage().getParameters().get('id')];
}
public Account getAccount() {
return account;
}
#RemoteAction
public static Product2 getProductRowData(string productId) {
Product2 product = [SELECT Id, Name, Family, Price__c, Description
FROM Product2
WHERE Id = :productId];
return product;
}
public List<SelectOption> getProductsLov() {
List<SelectOption> products = new List<SelectOption>();
productsList = [SELECT Id, Name, Family, Price__c, Description
FROM Product2
WHERE (Family = 'ShopProduct')
OR (Family = 'CourseParent')
OR (Family = 'SFCourseProgram')];
for (Product2 currProduct : productsList) {
products.add(new SelectOption(currProduct.Id, currProduct.Name));
}
return products;
}}
I found the issue! It was just a case of defining the button type as "button" because the default was "submit" and that caused the page to re-render
Related
enter image description here
<!DOCTYPE html>
<html>
<body>
<h1>HTML DOM Events</h1>
<h2>The onclick Event</h2>
<button onclick="myFunction()">Confirm</button>
<script>
function myFunction() {
var message = "You have selected:";
message += "Stmt1 \r\n stmt2 \r\n stmt2";
message += "\r\n";
message += "stmt2stmt2stmt2stmt2stmt2stmt2stmt2stmt2stmt2stmt2stmt2\n";
message += "stmt2stmt2stmt2stmt2stmt2stmt2stmt2stmt2stmt2stmt2stmt2stmt2";
status = confirm(message);
}
</script>
</body>
</html>
Here after 3rd line of the message , it is hidden.Also window size is not increasing to contain full text. Same is working fine with IE.
using System.Windows;
namespace CefSharp.Wpf.Example.Handlers
{
public class JsDialogHandler : CefSharp.Handler.JsDialogHandler
{
protected override bool OnJSDialog(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, CefJsDialogType dialogType, string messageText, string defaultPromptText, IJsDialogCallback callback, ref bool suppressMessage)
{
var b = (ChromiumWebBrowser)chromiumWebBrowser;
b.Dispatcher.InvokeAsync(() =>
{
if (dialogType == CefJsDialogType.Confirm)
{
var messageBoxResult = MessageBox.Show(messageText, $"A page at {originUrl} says:", MessageBoxButton.YesNo);
callback.Continue(messageBoxResult == MessageBoxResult.Yes);
}
else if(dialogType == CefJsDialogType.Alert)
{
var messageBoxResult = MessageBox.Show(messageText, $"A page at {originUrl} says:", MessageBoxButton.OK);
callback.Continue(messageBoxResult == MessageBoxResult.OK);
}
else if (dialogType == CefJsDialogType.Prompt)
{
var messageBoxResult = PromptDialog.Prompt(messageText, $"A page at {originUrl} says:", defaultPromptText);
callback.Continue(messageBoxResult.Item1, userInput: messageBoxResult.Item2);
}
});
return true;
}
}
}
//Assign your handler to the ChromiumWebBrowser instance
browser.JsDialogHandler = new CefSharp.Wpf.Example.Handlers.JsDialogHandler();
Full example added in commit https://github.com/cefsharp/CefSharp/commit/df8a6086a6bbb79280916c955015a1b58a421ddc
I have an online chat room, which works fine. However I would like to be able to send messages to offline users. How can I modify the code below to implement this change?
I would like to change ConnectedUsers to AllUsers, but for offline users I don't have a ConnectionId.
ChatHub.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using catchme.bg.Data;
using catchme.bg.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
namespace catchme.bg
{
[Authorize]
public class ChatHub : Hub
{
private CatchmeContext _context { get; set; }
public ChatHub(CatchmeContext context)
{
_context = context;
}
#region Data Members
static List<UserDetail> ConnectedUsers = new List<UserDetail>();
static List<MessageDetail> CurrentMessage = new List<MessageDetail>();
static List<PrivateMessageDetail> CurrentPrivateMessage = new List<PrivateMessageDetail>();
#endregion
#region Methods
public override async Task OnConnectedAsync()
{
var userName = Context.User.Identity.Name;
var id = Context.ConnectionId;
if (ConnectedUsers.Count(x => x.ConnectionId == id) == 0)
{
ConnectedUsers.Add(new UserDetail {ConnectionId = id, UserName = userName});
CurrentMessage.Clear();
CurrentPrivateMessage.Clear();
foreach (var user_name in ConnectedUsers.Select(u=>u.UserName).Distinct())
{
CurrentMessage.AddRange(GetMessageDetailsForUser(user_name).Result);
CurrentPrivateMessage.AddRange(GetPrivateMessageDetailsForUsers(Context.User.Identity.Name, user_name).Result);
}
// send to caller
await Clients.Caller.SendAsync("OnConnected", id, userName, ConnectedUsers, CurrentMessage, CurrentPrivateMessage);
// send to all except caller client
await Clients.AllExcept(id).SendAsync("NewUserConnected", id, userName, CurrentPrivateMessage);
}
}
public async Task SendMessageToAll(string message)
{
var userName = Context.User.Identity.Name;
// store last 100 messages in cache
AddMessageinCache(userName, message);
// Broad cast message
await Clients.All.SendAsync("MessageReceived", userName, message);
}
public async Task SendPrivateMessage(string toUserId, string message)
{
string fromUserId = Context.ConnectionId;
var toUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == toUserId);
var fromUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == fromUserId);
if (toUser != null && fromUser != null)
{
// send to
await Clients.Client(toUserId).SendAsync("SendPrivateMessage", fromUserId, fromUser.UserName, message);
// send to caller user
await Clients.Caller.SendAsync("SendPrivateMessage", toUserId, fromUser.UserName, message);
AddPrivateMessageinCache(fromUser.UserName, toUser.UserName, message);
}
}
public override async Task OnDisconnectedAsync(Exception ex)
{
var item = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
if (item != null)
{
ConnectedUsers.Remove(item);
var id = Context.ConnectionId;
await Clients.All.SendAsync("UserDisconnected", id, item.UserName);
}
}
#endregion
#region public Messages
private void AddMessageinCache(string userName, string message)
{
var publicMessage = new MessageDetail {UserName = userName, Message = message};
CurrentMessage.Add(publicMessage);
_context.MessageDetails.Add(publicMessage);
_context.SaveChanges();
if (CurrentMessage.Count > 100)
{
CurrentMessage.RemoveAt(0);
_context.MessageDetails.Remove(CurrentMessage[0]);
_context.SaveChanges();
}
}
#endregion
#region private Messages
private void AddPrivateMessageinCache(string userFrom, string userTo, string message)
{
var privateMessage = new PrivateMessageDetail { UserNameFrom = userFrom, UserNameTo = userTo, Message = message };
CurrentPrivateMessage.Add(privateMessage);
_context.PrivateMessageDetails.Add(privateMessage);
_context.SaveChanges();
var singleUserPrivateMessages = CurrentPrivateMessage.Where(u => u.UserNameFrom == userFrom && u.UserNameTo == userTo).ToList();
if (singleUserPrivateMessages.Count > 100)
{
CurrentPrivateMessage.Remove(singleUserPrivateMessages.First());
_context.PrivateMessageDetails.Remove(singleUserPrivateMessages.First());
_context.SaveChanges();
}
}
#endregion
public async Task<List<MessageDetail>> GetMessageDetailsForUser(string userName)
{
return await _context.MessageDetails.Where(u=>u.UserName==userName).ToListAsync();
}
public async Task<List<PrivateMessageDetail>> GetPrivateMessageDetailsForUsers(string userFrom, string userTo)
{
return await _context.PrivateMessageDetails.Where(u => u.UserNameFrom == userFrom && u.UserNameTo== userTo).ToListAsync();
}
}
}
Index.cshtml
#*<div>
<form id="send-form" action="#">
Send a message:
<input type="text" id="message-textbox" disabled/>
<button id="send-button" type="submit" disabled>Send</button>
</form>
<ul id="messages-list"></ul>
</div>
#section Scripts{
<script src="~/lib/signalr/signalr.min.js"></script>
<script src="~/js/chat.js"></script>
}*#
<link href="~/ChatStyle.css" rel="stylesheet" />
<link href="~/lib/jquery-ui/themes/base/jquery-ui.css" rel="stylesheet" />
#section Scripts{
#*<script src="~/lib/jquery-ui/ui/minified/core.js"></script>*#
<script src="~/lib/jquery-ui/jquery-ui.js"></script>
<script src="~/lib/jquery-ui/ui/minified/widget.js"></script>
<script src="~/lib/jquery-ui/ui/widgets/mouse.js"></script>
<script src="~/lib/jquery-ui/ui/widgets/draggable.js"></script>
<script src="~/lib/jquery-ui/ui/widgets/resizable.js"></script>
<script src="~/lib/signalr/signalr.min.js"></script>
<script src="~/js/chatjs.js"></script>
}
<div id="header">
Chat Room
</div>
<br />
<br />
<br />
<div id="divContainer">
#*<div id="divLogin" class="login">
<div>
Your Name:<br />
<input id="txtNickName" type="text" class="textBox" />
</div>
<div id="divButton">
<input id="btnStartChat" type="button" class="submitButton" value="Start Chat" />
</div>
</div>*#
<div id="divChat" class="chatRoom">
<div class="title">
Welcome to Chat Room [<span id='spanUser'></span>]
</div>
<div class="content">
<div id="divChatWindow" class="chatWindow">
</div>
<div id="divusers" class="users">
</div>
</div>
<div class="messageBar">
<input class="textbox" type="text" id="txtMessage" />
<input id="btnSendMsg" type="button" value="Send" class="submitButton" />
</div>
</div>
<input id="hdId" type="hidden" />
<input id="hdUserName" type="hidden" />
</div>
chatjs.js
$(function () {
setScreen(false);
var connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat")
.configureLogging(signalR.LogLevel.Information)
.build();
connection.start().catch(err => console.error(err.toString())).then(function () {
registerClientMethods(connection);
registerEvents(connection);
});
});
function setScreen(isLogin) {
if (!isLogin) {
$("#divChat").hide();
//$("#divLogin").show();
} else {
$("#divChat").show();
//$("#divLogin").hide();
}
}
function AddUser(connection, id, name, privateMessages) {
var userId = $('#hdId').val();
var code = "";
if (userId == id) {
code = $('<div class="loginUser">' + name + "</div>");
} else {
code = $('<a id="' + id + '" class="user" >' + name + '<a>');
$(code).dblclick(function () {
var id = $(this).attr('id');
if (userId != id)
OpenPrivateChatWindow(connection, id, name, privateMessages);
});
}
$("#divusers").append(code);
}
function AddMessage(userName, message) {
$('#divChatWindow').append('<div class="message"><span class="userName">' +
userName +
'</span>: ' +
message +
'</div>');
var height = $('#divChatWindow')[0].scrollHeight;
$('#divChatWindow').scrollTop(height);
}
function registerEvents(connection) {
$("#btnStartChat").click(function () {
var name = $("#txtNickName").val();
if (name.length > 0) {
connection.server.connect(name);
} else {
alert("Please enter name");
}
});
$('#btnSendMsg').click(function () {
var msg = $("#txtMessage").val();
if (msg.length > 0) {
//var userName = $('#hdUserName').val();
connection.send("SendMessageToAll", msg);
$("#txtMessage").val('');
}
});
$("#txtNickName").keypress(function (e) {
if (e.which == 13) {
$("#btnStartChat").click();
}
});
$("#txtMessage").keypress(function (e) {
if (e.which == 13) {
$('#btnSendMsg').click();
}
});
}
function registerClientMethods(connection) {
// Calls when user successfully logged in
connection.on("OnConnected",
function (id, userName, allUsers, messages, privateMessages) {
setScreen(true);
$('#hdId').val(id);
$('#hdUserName').val(userName);
$('#spanUser').html(userName);
// Add All Users
for (i = 0; i < allUsers.length; i++) {
AddUser(connection, allUsers[i].connectionId, allUsers[i].userName, privateMessages);
}
// Add Existing Public Messages
for (i = 0; i < messages.length; i++) {
AddMessage(messages[i].userName, messages[i].message);
}
// Add Existing Private Messages
for (i = 0; i < privateMessages.length; i++) {
AddMessage(privateMessages[i].userName, messages[i].message);
}
});
// On New User Connected
connection.on("NewUserConnected",
function (id, name, privateMesssages) {
AddUser(connection, id, name, privateMesssages);
});
// On User Disconnected
connection.on("UserDisconnected",
function (id, userName) {
$('#' + id).remove();
var ctrId = 'private_' + id;
$('#' + ctrId).remove();
var disc = $('<div class="disconnect">"' + userName + '" logged off.</div>');
$(disc).hide();
$('#divusers').prepend(disc);
$(disc).fadeIn(200).delay(2000).fadeOut(200);
});
connection.on("MessageReceived",
function (userName, message) {
AddMessage(userName, message);
});
connection.on("SendPrivateMessage",
function (windowId, fromUserName, message) {
var ctrId = 'private_' + windowId;
if ($('#' + ctrId).length == 0) {
createPrivateChatWindow(connection, windowId, ctrId, fromUserName);
}
$('#' + ctrId).find('#divMessage').append('<div class="message"><span class="userName">' +
fromUserName +
'</span>: ' +
message +
'</div>');
// set scrollbar
var height = $('#' + ctrId).find('#divMessage')[0].scrollHeight;
$('#' + ctrId).find('#divMessage').scrollTop(height);
});
}
function OpenPrivateChatWindow(connection, id, userName, privateMessages) {
var ctrId = 'private_' + id;
if ($('#' + ctrId).length > 0) return;
createPrivateChatWindow(connection, id, ctrId, userName);
//Add Private Messages
for (i = 0; i < privateMessages.length; i++) {
$('#' + ctrId).find('#divMessage').append('<div class="message"><span class="userName">' +
privateMessages[i].userNameFrom +
'</span>: ' +
privateMessages[i].message +
'</div>');
}
// set scrollbar
var height = $('#' + ctrId).find('#divMessage')[0].scrollHeight;
$('#' + ctrId).find('#divMessage').scrollTop(height);
}
function createPrivateChatWindow(connection, userId, ctrId, userName) {
var div = '<div id="' +
ctrId +
'" class="ui-widget-content draggable" rel="0">' +
'<div class="header">' +
'<div style="float:right;">' +
'<img id="imgDelete" style="cursor:pointer;" src="/images/delete.png"/>' +
'</div>' +
'<span class="selText" rel="0">' +
userName +
'</span>' +
'</div>' +
'<div id="divMessage" class="messageArea">' +
'</div>' +
'<div class="buttonBar">' +
'<input id="txtPrivateMessage" class="msgText" type="text" />' +
'<input id="btnSendMessage" class="submitButton button" type="button" value="Send" />' +
'</div>' +
'</div>';
var $div = $(div);
// DELETE BUTTON IMAGE
$div.find('#imgDelete').click(function () {
$('#' + ctrId).remove();
});
// Send Button event
$div.find("#btnSendMessage").click(function () {
$textBox = $div.find("#txtPrivateMessage");
var msg = $textBox.val();
if (msg.length > 0) {
connection.send("SendPrivateMessage", userId, msg);
$textBox.val('');
}
});
// Text Box event
$div.find("#txtPrivateMessage").keypress(function (e) {
if (e.which === 13) {
$div.find("#btnSendMessage").click();
}
});
AddDivToContainer($div);
}
function AddDivToContainer($div) {
$('#divContainer').prepend($div);
$div.draggable({
handle: ".header",
stop: function () {
}
});
////$div.resizable({
//// stop: function () {
//// }
////});
}
Please follow below stpes.
First In OnConnectedAsync(), take static list object and store user connectionId with
username.
you need to use OnDisconnectedAsync(). so whenever your any user get
offline, you will get call in this method and you can get connectionId in this method, find username from your list.
Now take one schema where you can manage, Pending to send message user List. add
useraname who is getting offline.
Now, When any user is connecting, first check whether that username is exist in
PendingToSendMessageUserList schema.
If yes, then first send him all pending message and then delete username from that
schema.
Hope you will understand, you need to implement it technically.
i have done the chat application using signalr client and chatsever implemented as class. Now i want to implement chat server as wcf service.
<link rel="stylesheet" href="Styles/jquery-ui.css" />
<script src="Scripts/jquery-1.8.2.js"></script>
<script src="Scripts/jquery-ui.js"></script>
<script type="text/javascript" src="Scripts/jquery.dialogextend.1_0_1.js"></script>
<script type="text/javascript" src="Scripts/jquery.signalR.js"></script>
<script type="text/javascript" src="Scripts/jQuery.tmpl.js"></script>
<script type="text/javascript" src="signalr/hubs"></script>
<script id="new-online-contacts" type="text/x-jquery-tmpl">
<div>
<ul>
{{each messageRecipients}}
<li id="chatLink${messageRecipientId}">${messageRecipientName}</li>
{{/each}}
</ul>
</div>
</script>
<script id="new-chatroom-template" type="text/x-jquery-tmpl">
<div id="chatRoom${chatRoomId}" class="chatRoom">
<ul id="messages${chatRoomId}" class="chatMessages">
</ul>
<form id="sendmessage${chatRoomId}" action="#">
<input type="text" id="newmessage${chatRoomId}" class="chatNewMessage"/>
<div class="clear"></div>
<input type="button" id="chatsend${chatRoomId}" value="Send" class="chatSend" OnClick="javascript:SRChat.sendChatMessage('${chatRoomId}')" />
<input type="button" id="chatend${chatRoomId}" value="End Chat" class="chatSend" OnClick="javascript:SRChat.endChat('${chatRoomId}')" />
</form>
</div>
</script>
<script id="new-chat-header" type="text/x-jquery-tmpl">
<div id="chatRoomHeader${chatRoomId}">
{{each messageRecipients}}
{{if $index == 0}}
${messageRecipientName}
{{else}}
, ${messageRecipientName}
{{/if}}
{{/each}}
<div>
</script>
<script id="new-message-template" type="text/x-jquery-tmpl">
<li class="message" id="m-${chatMessageId}">
<strong>${displayPrefix}</strong>
{{html messageText}}
</li>
</script>
<script id="new-notify-message-template" type="text/x-jquery-tmpl">
<li class="message" id="m-${chatMessageId}">
<strong>{{html messageText}}</strong>
</li>
</script>
<script type="text/javascript">
//<![CDATA[
$(document).ready(function () {
SRChat.attachEvents();
});
SRChat = new function () {
var Username = GetParameterValues('Username');
function GetParameterValues(param) {
var url = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < url.length; i++) {
var urlparam = url[i].split('=');
if (urlparam[0] == param) {
return urlparam[1];
}
}
}
var chatRooms = 0;
var numRand = Username;
var senderId = numRand;
var senderName = 'User :' + numRand;
var sRChatServer;
window.onbeforeunload = function () {
if (chatRooms > 0)
return "All chat instances will be ended!";
};
this.attachEvents = function () {
$("#userNameLabel").html(senderName);
if ($.connection != null) {
jQuery.support.cors = true;
$.connection.hub.url = 'signalr/hubs';
sRChatServer = $.connection.sRChatServer;
$.connection.hub.start({ transport: 'auto' }, function () {
sRChatServer.server.connect(senderId, senderName).fail(function (e) {
alert(e);
});
});
sRChatServer.client.initiateChatUI = function (chatRoom) {
var chatRoomDiv = $('#chatRoom' + chatRoom.chatRoomId);
if (($(chatRoomDiv).length > 0)) {
var chatRoomText = $('#newmessage' + chatRoom.chatRoomId);
var chatRoomSend = $('#chatsend' + chatRoom.chatRoomId);
var chatRoomEndChat = $('#chatend' + chatRoom.chatRoomId);
chatRoomText.show();
chatRoomSend.show();
chatRoomEndChat.show();
}
else {
var e = $('#new-chatroom-template').tmpl(chatRoom);
var c = $('#new-chat-header').tmpl(chatRoom);
chatRooms++;
//dialog options
var dialogOptions = {
"id": '#messages' + chatRoom.chatRoomId,
"title": c,
"width": 360,
"height": 365,
"modal": false,
"resizable": false,
"close": function () { javascript: SRChat.endChat('' + chatRoom.chatRoomId + ''); $(this).remove(); }
};
// dialog-extend options
var dialogExtendOptions = {
"close": true,
"maximize": false,
"minimize": true,
"dblclick": 'minimize',
"titlebar": 'transparent'
};
e.dialog(dialogOptions).dialogExtend(dialogExtendOptions);
$('#sendmessage' + chatRoom.chatRoomId).keypress(function (e) {
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
$('#chatsend' + chatRoom.chatRoomId).click();
return false;
}
});
}
};
sRChatServer.client.updateChatUI = function (chatRoom) {
var chatRoomHeader = $('#chatRoomHeader' + chatRoom.chatRoomId);
var c = $('#new-chat-header').tmpl(chatRoom);
chatRoomHeader.html(c);
};
sRChatServer.client.receiveChatMessage = function (chatMessage, chatRoom) {
sRChatServer.client.initiateChatUI(chatRoom);
var chatRoom = $('#chatRoom' + chatMessage.conversationId);
var chatRoomMessages = $('#messages' + chatMessage.conversationId);
var e = $('#new-message-template').tmpl(chatMessage).appendTo(chatRoomMessages);
e[0].scrollIntoView();
chatRoom.scrollIntoView();
};
sRChatServer.client.receiveLeftChatMessage = function (chatMessage) {
var chatRoom = $('#chatRoom' + chatMessage.conversationId);
var chatRoomMessages = $('#messages' + chatMessage.conversationId);
var e = $('#new-notify-message-template').tmpl(chatMessage).appendTo(chatRoomMessages);
e[0].scrollIntoView();
chatRoom.scrollIntoView();
};
sRChatServer.client.receiveEndChatMessage = function (chatMessage) {
var chatRoom = $('#chatRoom' + chatMessage.conversationId);
var chatRoomMessages = $('#messages' + chatMessage.conversationId);
var chatRoomText = $('#newmessage' + chatMessage.conversationId);
var chatRoomSend = $('#chatsend' + chatMessage.conversationId);
var chatRoomEndChat = $('#chatend' + chatMessage.conversationId);
chatRooms--;
var e = $('#new-notify-message-template').tmpl(chatMessage).appendTo(chatRoomMessages);
chatRoomText.hide();
chatRoomSend.hide();
chatRoomEndChat.hide();
e[0].scrollIntoView();
chatRoom.scrollIntoView();
};
sRChatServer.client.onGetOnlineContacts = function (chatUsers) {
var e = $('#new-online-contacts').tmpl(chatUsers);
var chatLink = $('#chatLink' + senderId);
e.find("#chatLink" + senderId).remove();
$("#chatOnlineContacts").html("");
$("#chatOnlineContacts").html(e);
};
}
};
this.sendChatMessage = function (chatRoomId) {
var chatRoomNewMessage = $('#newmessage' + chatRoomId);
if (chatRoomNewMessage.val() == null || chatRoomNewMessage.val() == "")
return;
var chatMessage = {
senderId: senderId,
senderName: senderName,
conversationId: chatRoomId,
messageText: chatRoomNewMessage.val()
};
chatRoomNewMessage.val('');
chatRoomNewMessage.focus();
sRChatServer.server.sendChatMessage(chatMessage).fail(function (e) {
alert(e);
});
return false;
};
this.endChat = function (chatRoomId) {
var chatRoomNewMessage = $('#newmessage' + chatRoomId);
var chatMessage = {
senderId: senderId,
senderName: senderName,
conversationId: chatRoomId,
messageText: chatRoomNewMessage.val()
};
chatRoomNewMessage.val('');
chatRoomNewMessage.focus();
sRChatServer.server.endChat(chatMessage).fail(function (e) {
//alert(e);
});
};
this.initiateChat = function (toUserId, toUserName) {
if (sRChatServer == null) {
alert("Problem in connecting to Chat Server. Please Contact Administrator!");
return;
}
sRChatServer.server.initiateChat(senderId, senderName, toUserId, toUserName).fail(function (e) {
alert(e);
});
};
};
//]]>
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="userNameLabel">
</div>
<br />
<br />
<div id="chatRooms">
</div>
<div id="chatOnlineContacts">
</div>
</div>
</form>
</body>
My server side code is
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using SignalR.Hubs;
namespace SRChat
{
[HubName("sRChatServer")]
public class SRChatServer:Hub
{
#region Private Variables
private static readonly ConcurrentDictionary<string, MessageRecipient> _chatUsers = new ConcurrentDictionary<string, MessageRecipient>(StringComparer.OrdinalIgnoreCase);
private static readonly ConcurrentDictionary<string, ChatRoom> _chatRooms = new ConcurrentDictionary<string, ChatRoom>(StringComparer.OrdinalIgnoreCase);
#endregion
#region Public Methods
public bool Connect(string userId, string userName)
{
try
{
if (string.IsNullOrEmpty(userId) | string.IsNullOrEmpty(userName))
{
return false;
}
if (GetChatUserByUserId(userId) == null)
{
AddUser(userId, userName);
}
else
{
ModifyUser(userId, userName);
}
SendOnlineContacts();
return true;
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in connecting to chat server!");
}
}
public override Task Disconnect()
{
try
{
DeleteUser(Context.ConnectionId);
return null;
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in disconnecting from chat server!");
}
}
public bool InitiateChat(string fromUserId, string fromUserName, string toUserId, string toUserName)
{
try
{
if (string.IsNullOrEmpty(fromUserId) || string.IsNullOrEmpty(fromUserName) || string.IsNullOrEmpty(toUserId) || string.IsNullOrEmpty(toUserName))
{
return false;
}
var fromUser = GetChatUserByUserId(fromUserId);
var toUser = GetChatUserByUserId(toUserId);
if (fromUser != null && toUser != null)
{
if (!CheckIfRoomExists(fromUser, toUser))
{
//Create New Chat Room
ChatRoom chatRoom = new ChatRoom();
chatRoom.chatRoomInitiatedBy = fromUser.messageRecipientId;
chatRoom.chatRoomInitiatedTo = toUser.messageRecipientId;
chatRoom.messageRecipients.Add(fromUser);
chatRoom.messageRecipients.Add(toUser);
//create and save blank message to get new conversation id
ChatMessage chatMessage = new ChatMessage();
chatMessage.messageText = "Chat Initiated";
chatMessage.senderId = fromUser.messageRecipientId;
chatMessage.senderName = fromUser.messageRecipientName;
fromUser.chatRoomIds.Add(chatRoom.chatRoomId);
toUser.chatRoomIds.Add(chatRoom.chatRoomId);
//Create SignalR Group for this chat room and add users connection to it
Groups.Add(fromUser.connectionId, chatRoom.chatRoomId);
Groups.Add(toUser.connectionId, chatRoom.chatRoomId);
//Add Chat room object to collection
if (_chatRooms.TryAdd(chatRoom.chatRoomId, chatRoom))
{
//Generate Client UI for this room
Clients[fromUser.connectionId].initiateChatUI(chatRoom);
}
}
}
return true;
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in starting chat!");
}
}
public bool EndChat(ChatMessage chatMessage)
{
try
{
ChatRoom chatRoom;
if (_chatRooms.TryGetValue(chatMessage.conversationId, out chatRoom))
{
if (_chatRooms[chatRoom.chatRoomId].chatRoomInitiatedBy == chatMessage.senderId)
{
chatMessage.messageText = string.Format("{0} left the chat. Chat Ended!", chatMessage.senderName);
if (_chatRooms.TryRemove(chatRoom.chatRoomId, out chatRoom))
{
Clients[chatRoom.chatRoomId].receiveEndChatMessage(chatMessage);
foreach (MessageRecipient messageReceipient in chatRoom.messageRecipients)
{
if (messageReceipient.chatRoomIds.Contains(chatRoom.chatRoomId))
{
messageReceipient.chatRoomIds.Remove(chatRoom.chatRoomId);
Groups.Remove(messageReceipient.connectionId, chatRoom.chatRoomId);
}
}
}
}
else
{
MessageRecipient messageRecipient = GetChatUserByUserId(chatMessage.senderId);
if (messageRecipient != null && messageRecipient.chatRoomIds.Contains(chatRoom.chatRoomId))
{
chatRoom.messageRecipients.Remove(messageRecipient);
messageRecipient.chatRoomIds.Remove(chatRoom.chatRoomId);
if (chatRoom.messageRecipients.Count < 2)
{
chatMessage.messageText = string.Format("{0} left the chat. Chat Ended!", chatMessage.senderName);
if (_chatRooms.TryRemove(chatRoom.chatRoomId, out chatRoom))
{
Clients[chatRoom.chatRoomId].receiveEndChatMessage(chatMessage);
foreach (MessageRecipient messageReceipient in chatRoom.messageRecipients)
{
if (messageReceipient.chatRoomIds.Contains(chatRoom.chatRoomId))
{
messageReceipient.chatRoomIds.Remove(chatRoom.chatRoomId);
Groups.Remove(messageReceipient.connectionId, chatRoom.chatRoomId);
}
}
}
}
else
{
chatMessage.messageText = string.Format("{0} left the chat.", chatMessage.senderName);
Groups.Remove(messageRecipient.connectionId, chatRoom.chatRoomId);
Clients[messageRecipient.connectionId].receiveEndChatMessage(chatMessage);
Clients[chatRoom.chatRoomId].receiveLeftChatMessage(chatMessage);
Clients[chatRoom.chatRoomId].updateChatUI(chatRoom);
}
}
}
}
else
{
throw new InvalidOperationException("Problem in ending chat!");
}
return true;
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in ending chat!");
}
}
public bool SendChatMessage(ChatMessage chatMessage)
{
try
{
ChatRoom chatRoom;
if (_chatRooms.TryGetValue(chatMessage.conversationId, out chatRoom))
{
chatMessage.chatMessageId = Guid.NewGuid().ToString();
chatMessage.timestamp = DateTime.Now;
Clients[chatMessage.conversationId].receiveChatMessage(chatMessage, chatRoom);
return true;
}
else
{
throw new InvalidOperationException("Problem in sending message!");
}
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in sending message!");
}
}
private bool SendOnlineContacts()
{
try
{
OnlineContacts onlineContacts = new OnlineContacts();
foreach (var item in _chatUsers)
{
onlineContacts.messageRecipients.Add(item.Value);
}
Clients.onGetOnlineContacts(onlineContacts);
return false;
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in getting contacts!");
}
}
#endregion
#region Private Methods
private Boolean CheckIfRoomExists(MessageRecipient fromUser, MessageRecipient toUser)
{
foreach (string chatRoomId in fromUser.chatRoomIds)
{
Int32 count = (from mr in _chatRooms[chatRoomId].messageRecipients
where mr.messageRecipientId == toUser.messageRecipientId
select mr).Count();
if (count > 0)
{
return true;
}
}
foreach (string chatRoomId in toUser.chatRoomIds)
{
Int32 count = (from mr in _chatRooms[chatRoomId].messageRecipients
where mr.messageRecipientId == fromUser.messageRecipientId
select mr).Count();
if (count > 0)
{
return true;
}
}
return false;
}
private MessageRecipient AddUser(string userId, string userName)
{
var user = new MessageRecipient();
user.messageRecipientId = userId;
user.messageRecipientName = userName;
user.connectionId = Context.ConnectionId;
_chatUsers[userId] = user;
return user;
}
private MessageRecipient ModifyUser(string userId, string userName)
{
var user = GetChatUserByUserId(userId);
user.messageRecipientName = userName;
user.connectionId = Context.ConnectionId;
_chatUsers[userId] = user;
return user;
}
private Boolean DeleteUser(string userId, string userName)
{
var user = GetChatUserByUserId(userId);
if (user != null && _chatUsers.ContainsKey(user.messageRecipientId))
{
MessageRecipient messageRecipient;
return _chatUsers.TryRemove(user.messageRecipientId, out messageRecipient);
}
return false;
}
private Boolean DeleteUser(string connectionId)
{
var returnValue = false;
var user = GetChatUserByConnectionId(connectionId);
if (user != null && _chatUsers.ContainsKey(user.messageRecipientId))
{
MessageRecipient messageRecipient;
returnValue = _chatUsers.TryRemove(user.messageRecipientId, out messageRecipient);
//remoave from all groups and chatrooms
foreach (string chatRoomId in messageRecipient.chatRoomIds)
{
_chatRooms[chatRoomId].messageRecipients.Remove(messageRecipient);
Groups.Remove(messageRecipient.connectionId, chatRoomId);
//notify user left chat
ChatMessage chatMessage = new ChatMessage();
chatMessage.conversationId = chatRoomId;
chatMessage.senderId = messageRecipient.messageRecipientId;
chatMessage.senderName = messageRecipient.messageRecipientName;
if (_chatRooms[chatRoomId].chatRoomInitiatedBy == messageRecipient.messageRecipientId)
{
chatMessage.messageText = string.Format("{0} left the chat. Chat Ended!", messageRecipient.messageRecipientName);
ChatRoom chatRoom;
if (_chatRooms.TryRemove(chatRoomId, out chatRoom))
{
foreach (MessageRecipient messageReceipient in chatRoom.messageRecipients)
{
if (messageReceipient.chatRoomIds.Contains(chatRoomId))
{
messageReceipient.chatRoomIds.Remove(chatRoomId);
}
}
Clients[chatRoomId].receiveEndChatMessage(chatMessage);
}
}
else
{
if (_chatRooms[chatRoomId].messageRecipients.Count() < 2)
{
chatMessage.messageText = string.Format("{0} left the chat. Chat Ended!", messageRecipient.messageRecipientName);
ChatRoom chatRoom;
if (_chatRooms.TryRemove(chatRoomId, out chatRoom))
{
foreach (MessageRecipient messageReceipient in chatRoom.messageRecipients)
{
if (messageReceipient.chatRoomIds.Contains(chatRoomId))
{
messageReceipient.chatRoomIds.Remove(chatRoomId);
}
}
Clients[chatRoomId].receiveEndChatMessage(chatMessage);
}
}
else
{
chatMessage.messageText = string.Format("{0} left the chat.", messageRecipient.messageRecipientName);
Clients[chatRoomId].receiveLeftChatMessage(chatMessage);
}
}
}
}
return returnValue;
}
private MessageRecipient GetChatUserByUserId(string userId)
{
return _chatUsers.Values.FirstOrDefault(u => u.messageRecipientId == userId);
}
private MessageRecipient GetChatUserByConnectionId(string connectionId)
{
return _chatUsers.Values.FirstOrDefault(u => u.connectionId == connectionId);
}
#endregion
}
}
i want to implement this one as wcf service or web service. please help me in advance
I think the best way to achieve that is to create a windows managed service.(Cause you can't control the lifetime of your service when hosted in IIS with a per-call configuration).
So you should create a new windows service and host both your wcf service and signalr (it's only an idea but I think the code can looks like that):
public class HostWindowService : ServiceBase
{
public ServiceHost serviceHost = null;
public HostWindowService()
{
ServiceName = "WCFWindowsServiceSample";
}
public static void Main()
{
ServiceBase.Run(new HostWindowService());
}
protected override void OnStart(string[] args)
{
//host wcf service
if (serviceHost != null)
{
serviceHost.Close();
}
serviceHost = new ServiceHost(typeof(WCFService));
serviceHost.Open();
//host signalr
Task.Run(() => SignalRHost());
}
private void SignalRHost()
{
try
{
SignalR = WebApp.Start("http://localhost:8080");
}
catch (TargetInvocationException)
{
WriteToConsole("A server is already running at " + "http://localhost:8080");
return;
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
}
References : How to: Host a WCF Service in a Managed Windows Service and Self-Hosting SignalR in a Windows Service
InquiryOrderViewModel
public class InquiryOrderViewModel
{
public InquiryOrder InquiryOrder { get; set; }
public List<InquiryOrderDetail> InquiryOrderDetails { get; set; }
}
InquiryOrderIndex View and the Script to add items
#model eKnittingData.InquiryOrderViewModel
#using (Html.BeginForm("Save", "InquiryOrder"))
{
<div id="editorRows">
#foreach (var item in Model.InquiryOrderDetails)
{
Html.RenderPartial("_DetailEditorRow", item);
}
</div>
#Html.ActionLink("Add another...", null, null, new { id = "addItem" })
<div class="col-md-6"> <input type="submit" value="Save" class="btn btn-success" /> </div>
}
<script>
$('#addItem').click(function (e) {
e.preventDefault();
var isExist = false;
$('.editorRow').each(function () {
if ($(this).children('.class01').val() == 0 || $(this).children('.class02').find("option:selected").text() == "Select") {
isExist = true;
return false;
}
});
if (isExist == false) {
$('.editorRow').each(function () {
$(".editorRow").children().attr("disabled", "disabled");
});
$.ajax({
url: '#Url.Action("BlankEditorRow", "InquiryOrder")',
cache: false,
success: function (data) {
$("#editorRows").append(data);
}
});
}
});
</script>
DetailEditorRow PartialView
#model eKnittingData.InquiryOrderDetail
#using eKnitting.Helpers
#using (Html.BeginCollectionItem("InquiryOrderDetails"))
{
<div class="editorRow">
#Html.DropDownListFor(a => a.ComponentId, (SelectList)ViewBag.CompList, "Select", new { Class = "class02" })
#Html.DropDownListFor(a => a.DesignCodeId, (SelectList)ViewBag.DCodeList, "Select", new { Class = "class03" })
#Html.TextBoxFor(a => a.NoOfParts, new { Class = "class01" })
delete
</div>
}
ActionResult which returns PartialView
public ActionResult BlankEditorRow()
{
var objContext = new KnittingdbContext();
ViewBag.CompList = new SelectList(objContext.Components, "ComponentId", "ComponentName");
ViewBag.DCodeList = new SelectList(objContext.DesignCodes, "DesignCodeId", "DesignCodeCode");
return PartialView("_DetailEditorRow", new InquiryOrderDetail());
}
ActionResult for 'GET'
var objContext = new KnittingdbContext();
var newIovm = new InquiryOrderViewModel();
var newIo = new InquiryOrder();
//initial item
var newIoD = new List<InquiryOrderDetail>
{
new InquiryOrderDetail()
};
newIovm.InquiryOrder = newIo;
newIovm.InquiryOrderDetails = newIoD;
ViewBag.CompList = new SelectList(objContext.Components, "ComponentId", "ComponentName");
ViewBag.DCodeList = new SelectList(objContext.DesignCodes, "DesignCodeId", "DesignCodeCode");
return View(newIovm);
ActionResult for 'POST'
public ActionResult Save(InquiryOrderViewModel inquiryOrderViewModel)
{
.................
}
When i click the add button im able to add items dynamically. But for PostBack it gives me only the lastly appended item. I checked it by putting a break point on post ActionResult. How can i get the whole collection for PostBack? Where did i go wrong? All help appreciated. Thanks!
Your scripts sets a variable var isExist = false;. When you add a new item, you check if the value is false (which it is if you got that far) and then disable all existing inputs.
Disabled form controls do not post back, hence you only get the values for the last row you have added.
Its unclear why you would want to disable them, but if you want to prevent editing of existing rows, the make them readonly
$(".editorRow").children().prop("readonly", true);
Child ajax form redirects to the URL http://www.AppName/Email/Email/AttachmentList instead of refreshing the AttachmentList view only.
Here is the child form (View Name: Attachment List)
#foreach (var attachment in Model.Attachments)
{
<li>
#using (Ajax.BeginForm("RemoveAttachment", "Email", new { area = "Email" }, new FSIAjaxOptions { UpdateTargetId = "uploadedFilesSection" }, new { #id = "fromEditRole" + attachment.IdString }))
{
#Html.HiddenFor(model => attachment.IdString)
<span><a `enter code here`href="#Url.Content("~/File/GetFile")?folder=EmailAttachments&file=#(attachment.AttachName)" target="_blank">#attachment.OriginalName</a></span>
<button type="submit" class="imageButton removeButton" title="Remove"></button>
}
</li>
}
Here is the Controller Action
[Authorize]
[HttpPost]
public ActionResult RemoveAttachment(FormCollection fm)
{
EmailViewModel model = SessionData.GetCurrentObject<EmailViewModel>();
if ((fm.AllKeys.Contains("attachment.IdString")) && !string.IsNullOrEmpty(fm["attachment.IdString"]))
{
var attachment = model.Attachments.Where(x => x.IdString == fm["attachment.IdString"]).FirstOrDefault();
if (attachment != null)
{
FileHelper.RemoveFile("EmailAttachments","",attachment.AttachName);
Directory.Delete(WebConfig.SharedFileContainer + #"\EmailAttachments\" + attachment.IdString, true);
model.Attachments.Remove(attachment);
}
SessionData.SaveCurrentObject<EmailViewModel>(model);
}
return View("AttachmentList", "Email", new { area = "Email" });
}
public ActionResult AttachmentList()
{
EmailViewModel email = SessionData.GetCurrentObject<EmailViewModel>();
if (Request.IsAjaxRequest())
{
return PartialView(email);
}
else
{
return View("AttachmentList", "~/Views/Shared/Wrapper.cshtml", email);
}
}
Make sure you have the ajax js file referenced.