Trigger web socket onmessage event manually - javascript

I have a small shoutbox chat written with PHP and Ratchet.
In JS, I have the following event, which fires a regular js function which happens on pressing enter at the moment:
socket.onmessage = function(evt) {
var data = JSON.parse(evt.data);
addMessage(data.msg);
};
That works, but I want to write a message "user is typing" while the user is typing and before the message is actually sent, so I am guessing I need to call the onmessage event manually, is that possible?
relevant js:
var chat = $('#chatwindow');
var msg = $('#messagebox');
function addMessage(msg) {
chat.append("<p>" + msg + "</p>");
}
msg.keypress(function( event ) {
if ( event.which != 13 ) {
return;
}
event.preventDefault();
if (msg.val() == "" || !open) {
return;
}
socket.send(JSON.stringify({
msg: msg.val()
}));
addMessage(msg.val());
msg.val("");
});
socket.onmessage = function(evt) {
var data = JSON.parse(evt.data);
addMessage(data.msg);
};

You have evt.data which is being passed from the server. Add another type of event, which will trigger when a user is typing.
Something like:
socket.onmessage = function(evt) {
var data = JSON.parse(evt.data);
if ( data.type == 'message' ) {
addMessage(data.msg);
} else if ( data.type == 'typing' ) {
showUserIsTyping();
} else if ( data.type == 'typingStopped' ) {
hideUserIsTyping();
}
};
All you'd need to do is send a message to the server when the user is typing, and maybe add a timeout, and send an event of typingStopped if the user hasn't typed anything in like 10 seconds or so.
Here is an example using the code you provided:
var msg = $('#messagebox');
function addMessage(msg) {
chat.append("<p>" + msg + "</p>");
}
msg.keypress(function( event ) {
event.preventDefault();
if (msg.val() == "" || !open) {
return;
}
//User pressed enter
if ( event.which == 13 ) {
socket.send(JSON.stringify({
type: 'message'
msg: msg.val()
}));
addMessage(msg.val());
msg.val("");
} else {
//Keypress, but not enter
socket.send(JSON.stringify({
type: 'typing'
}));
}
});
socket.onmessage = function(evt) {
var data = JSON.parse(evt.data);
switch ( data.type )
{
case 'message':
addMessage(data.msg);
break;
case 'typing':
notifyUserTyping(); //Create this function, and have it show/hide a "Typing..." textbox or similar.
break;
}
};

Related

Display response description from shopify api (cart/add.js)

I'm trying to show an alert every time customer is trying to add variant quantity that is bigger than available quantity. When that's happens I see 422 response from add.js -
{status: 422, message: "Cart Error",…}
description: "All 1 Black Basic High Waisted Briefs - black / 1 are in your cart."
message: "Cart Error"
status: 422
I need to display the description for customers, how that is possible?
Here is my code -
var shopifyAjaxAddURL = '/cart/add.js';
var shopifyAjaxCartURL = '/cart.js';
var shopifyAjaxStorePageURL = '/search';
$(document).on('submit', 'form[action="/cart/add"]:not(.noAJAX, .feedback-go_to_cart)', function(e) {
var $form = $(this);
//Add to cart
$.post(shopifyAjaxAddURL, $form.serialize(), function(itemData) {
//Enable add button
$btn.html(theme.icons.tick + ' ' + {{ 'products.product.added_to_cart' | t | json }});
setTimeout(function(){
//Not added, show message
if(typeof(data) != 'undefined' && typeof(data.status) != 'undefined') {
var jsonRes = $.parseJSON(data.responseText);
window.showQuickPopup(jsonRes.description, $btn);
} else {
//Some unknown error? Disable ajax and submit the old-fashioned way.
$form.addClass('noAJAX');
$form.submit();
}
});
Your code seems bit buggy. Possible solution could be, check if the status is 422 and send the customer an alert message.
if( itemData.status === 422 ) { alert('Quantity not available in the inventory') }
Full code might look like:
var shopifyAjaxAddURL = '/cart/add.js';
var shopifyAjaxCartURL = '/cart.js';
var shopifyAjaxStorePageURL = '/search';
$(document).on('submit', 'form[action="/cart/add"]:not(.noAJAX, .feedback-go_to_cart)', function (e) {
var $form = $(this);
//Add to cart
$.post(shopifyAjaxAddURL, $form.serialize(), function (itemData) {
if( itemData.status === 422 ) { alert('Quantity not available in the inventory') }
else {
//Enable add button
$btn.html(theme.icons.tick + ' ' + {{ 'products.product.added_to_cart' | t | json }});
setTimeout(function () {
//Not added, show message
if (typeof (data) != 'undefined' && typeof (data.status) != 'undefined') {
var jsonRes = $.parseJSON(data.responseText);
window.showQuickPopup(jsonRes.description, $btn);
} else {
//Some unknown error? Disable ajax and submit the old-fashioned way.
$form.addClass('noAJAX');
$form.submit();
}
}
});

Open new tab onclick JS event using handler ashx

I have a login button with onclick event...onclick = "login();"
I successfully logged in ...but I wanted to open new tab instead.
This is my javascript:
login = function() {
if ($("#UserName").val().length == 0) {
return;
}
if ($("#Password").val().length == 0) {
return;
}
var logindata = new Object();
logindata.UserName = $("#UserName").val();
logindata.Password = $("#Password").val();
locustraxx.showLoading("loginformDiv");
locustraxx.doAjaxPostback('//example.com/LoginHandler.ashx', logindata, null, null,
function(data, textStatus, jqXHR) {
var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
if (data.success == true) {
if ($("#Remember").is(':checked')) {
$.cookie('remember', $("#UserName").val() + '|' + $("#Password").val(), {
expires: 36500,
path: '/'
});
}
var retUrl = $.QueryString("ReturnUrl");
if (retUrl == undefined || retUrl == null) {
window.location.replace(data.data, '_blank');
} else {
window.location.href = decodeURIComponent(retUrl).replace(/\~~/g, ".");
}
if (isChrome) {
// clearCookies();
}
return false;
} else {
alert(data.message);
$("#UserName").focus();
}
}, null,
function() {
login.hideLoading("loginformDiv");
});
}
I tried _blank... window open, but to no avail
Could you please specify better what you have tried so far in theory you should be OK with:
window.open('https://www.google.com', '_blank');
If It isn’t working please specify the error output of the console.
There is also a known issue in which the browser opens a new window instead of a new tab, but that has to do with the user preferences, nothing to do about that. See here.

Contact Form Backend needed, Frontend given

I used to host a website at carrd.co with the pro plus plan. I chose the expensive plan because of the possibility to download the website and host it on an own server.
What I did not know, was that this did not include server-side code.
My problem is, that I have the front end code, but every PHP code I try fails to interact with this code. Since I can only develop with Java, I cannot get to a solution by myself.
The issue is that I do not know what the next step is to make this code work on my server so that it successfully sends me an email when this form is submitted by a user. I do not have any backend code and do not know where to start.
1) where can i put a PHP file to answer to this request? How do i have to name it?
2) how can i parse the arguments?
3) how do i have to format the answer from the php script to the ajax script?
Could you guys please help here? Thanks a lot!!!
(i might even be able to solve this with some good hints if you cannot be bothered to provide a full solution! I'm thankful for any advice!)
The frontend code:
Form:
<form id="form02" method="post">
<div class="inner">
<div class="field"><input type="text" name="name" id="name" placeholder="Name"
maxlength="128"/></div>
<div class="field"><input type="email" name="email" id="email"
placeholder="Email" maxlength="128"/></div>
<div class="field"><input type="text" name="fname" id="-fname" placeholder="Fname"
maxlength="128"/></div>
<div class="field"><textarea name="message" id="message" placeholder="Message"
maxlength="16384"></textarea></div>
<div class="actions">
<button type="submit">Send Message</button>
</div>
</div>
<input type="hidden" name="id" value="form02"/>
</form>
Script:
function form(id, settings) {
var _this = this;
this.id = id;
this.mode = settings.mode;
this.method = settings.method;
this.success = settings.success;
this.preHandler = ('preHandler' in settings ? settings.preHandler : null);
this.failure = ('failure' in settings ? settings.failure : null);
this.optional = ('optional' in settings ? settings.optional : []);
this.$form = $('#' + this.id);
this.$form.addEventListener('submit', function (event) {
_this.submit(event);
});
this.$form.addEventListener('keydown', function (event) {
if (event.keyCode == 13 && event.ctrlKey) {
event.preventDefault();
event.stopPropagation();
_this.submit(event);
}
});
var x = $('#' + this.id + ' input[name="' + settings.hid + '"]');
if (x) {
x.disabled = true;
x.parentNode.style.display = 'none';
}
this.$submit = $('#' + this.id + ' button[type="submit"]');
this.$submit.disabled = false;
};form.prototype.notify = function (type, message) {
if (message.match(/^(#[a-zA-Z0-9\_\-]+|[a-z0-9\-\.]+:[a-zA-Z0- 9\~\!\#\#$\%\&\-\_\+\=\;\,\.\?\/\:]+)$/)) location.href = message; else alert((type == 'failure' ? 'Error: ' : '') + message);
};
form.prototype.submit = function (event) {
var _this = this, result, handler, fd, k, x, $f, $ff;
event.preventDefault();
if (this.$submit.disabled) return;
result = true;
$ff = this.$form.elements;
for (k in $ff) {
$f = $ff[k];
if ($f.type != 'text' && $f.type != 'email' && $f.type != 'textarea' && $f.type != 'select-one') continue;
if ($f.disabled) continue;
if ($f.value === '' || $f.value === null) {
if (this.optional.indexOf($f.name) !== -1) continue;
result = false;
} else {
x = '';
switch ($f.type) {
case 'email':
x = "^([a-zA-Z0-9\\_\\-\\.\\+]+)#([a-zA-Z0-9\\- \\.]+)\\.([a-zA-Z]+)$";
break;
case 'select':
x = "^[a-zA-Z0-9\\-]$";
break;
default:
case 'text':
case 'textarea':
x = "^[^\\<\\>]+$";
break;
}
result = result && $f.value.match(new RegExp(x));
}
if (!result) break;
}
if (!result) {
this.notify('failure', 'Missing and/or invalid fields. Please try again.');
return;
}
if (_this.method == 'get') {
_this.$form.submit();
return;
}
if (x = $(':focus')) x.blur();
this.$submit.disabled = true;
this.$submit.classList.add('waiting');
handler = function (values) {
var x, k, data;
data = new FormData(_this.$form);
if (values) for (k in values) data.append(k, values[k]);
x = new XMLHttpRequest();
x.open('POST', ['', 'post', _this.mode].join('/'));
x.send(data);
x.onreadystatechange = function () {
var result = false, message = 'Sorry, something went wrong. Please try again later.', alert = true, o;
if (x.readyState != 4) return;
if (x.status == 200) {
o = JSON.parse(x.responseText);
if (o) {
if ('result' in o) result = (o.result === true);
if (('message' in o) && o.message) message = o.message;
if ('alert' in o) alert = (o.alert === true);
}
}
_this.$submit.classList.remove('waiting');
if (result) {
_this.$form.reset();
if (alert) window.alert(message); else _this.notify('success', (_this.success ? _this.success : message));
} else {
if (alert) window.alert(message); else _this.notify('failure', (_this.failure ? _this.failure : message));
}
_this.$submit.disabled = false;
};
};
if (_this.preHandler) (_this.preHandler)(_this, handler); else (handler)();
};
new form('form02', {mode: 'contact', method: 'post', hid: 'fname', success: '#contact-done',});
An html form normally uses an action parameter to specify a url for the script to submit the form data to. However it looks like your javascript code is hard-coded to create an ajax post back to a url at /post/contact, which may explain why the examples you have tried do not work.
Yes, you do need a script of some kind on your server to process the response, but it doesn't have to be PHP - whatever your hosting provider supports, and whatever is capable of handling what you want to do with the data.

How to return false from a main function after an ajax callback?

I perform an edit to ensure against duplicate emails by making an ajax call and supplying a callback. If a duplicate exists, I want to return false from submit event. Is there an elegant way to achieve this without setting async=false? What I tried (see emailCallback) is not working.
submit event
EDIT (included the rest of the submit handler).
$("#form-accounts").on("submit", function (e) {
e.preventDefault();
if (!$(this).get(0).checkValidity()) return false;
if (!customValidation(true, false)) return;
checkDupEmail(emailCallback);
function emailCallback(result) {
if (result) return (function () { return false } ());
}
if ($("#submit").text() == "Create Account") {
var formData = $("#form-accounts").serialize().replace("''", "'");
ajax('post', 'php/accounts.php', formData + "&action=create-account", createSuccess);
function createSuccess(result) {
if (isNaN(result)) {
showMessage(0, result);
return;
}
localStorage.setItem("account-id", result);
debugger
setUsertype($("input[name=user-type]:checked").val());
showMessage(1, "Account Created");
};
return
}
var rString = randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
};
var anRandom = randomString(14, rString);
$("#code").val(anRandom);
console.log("v-code=" + anRandom);
$("#submit").css({ 'display': 'none' });
$("#verify").css({ 'display': 'block' });
var subject = "Writer's Tryst Verification Code"
$("#subject").val(subject);
var msg = "This mail is intended for the person who requested verification of email ownership at Writers-Tryst (" + getWriterTrystURL() + ").\n\n" + "Double click on the code below and then copy it. Return to our website and and paste the code.\n\nYour verification code: \n\n" + anRandom;
$("#msg").val(msg);
var formData = $("#form-accounts").serialize().replace("''", "'");
ajax('post', 'php/sendmail.php', formData, successMail, "create-account error: ");
function successMail(result) {
$("#ver-email-msg").val("An email has been sent to you. Double-click the verification code then copy and paste it below.").css({ 'display': 'block' });
}
});
function checkDupEmail(callback) {
var data = {};
data.action = "validate-email";
data.email = $("#email").val();
ajax('post', 'php/accounts.php', data, emailSuccess);
function emailSuccess(result) {
if (parseInt(result) > 0) {
showMessage(0, "The email address is in use. Please supply another or login instead of creating a new account.")
callback(true);
} else callback(false);
}
}
Instead of passing a callback, why don't you just submit the form when your Ajax call completes successfully?
$("#form-accounts").on("submit", function (e) {
// Always cancel the submit initially so the form is not submitted until after the Ajax call is complete
e.preventDefault();
...
checkDupEmail(this);
...
});
function checkDupEmail(form) {
var data = {};
data.action = "validate-email";
data.email = $("#email").val();
ajax('post', 'php/accounts.php', data, function(result) {
if (parseInt(result) > 0) {
showMessage(0, "The email address is in use. Please supply another or login instead of creating a new account.")
} else {
form.submit();
}
}
}
A better approach than that would be to submit your form using Ajax. That would eliminate the need for two calls to the server.

Banning system with Meteor accounts?

I'm working on a chat app with meteor that uses accounts-ui and accounts-twitter. I want to be able to ban people if they misuse the website but I'm not sure how to do this or if it is even possible. Is there a way to do this? Here is the code I use to run the chat app part of it:
ui.js:
// render all of our messages in the ui
Template.chatBox.helpers({
"messages": function() {
return chatCollection.find();
}
});
// get the value for handlerbar helper user
Template.chatMessage.helpers({
"user": function() {
if(this.userId == 'me') {
return this.userId;
} else if(this.userId) {
getUsername(this.userId);
return Session.get('user-' + this.userId);
} else {
return 'anonymous-' + this.subscriptionId;
}
}
});
// when Send Chat clicked at the message to the collection
Template.chatBox.events({
"click #send": function() {
if (Meteor.user() == null) {
alert("You must login to post");
return;
}
$('#messages').animate({"scrollTop": $('#messages')[0].scrollHeight}, "fast");
var message = $('#chat-message').val();
// check to see if the message has any characters in it
if (message.length < 1) {
alert("You must enter a message to post.");
return;
}
if (message.length > 200) {
alert("Your message is too long... they can't read that fast!");
return;
}
chatCollection.insert({
userId: 'me',
message: message
});
$('#chat-message').val('');
//Validation
var bot =Check_bots();
if(bot==false)
{
//add the message to the stream
chatStream.emit('chat', message);
}
else
{
alert("Slow down! No need to post that fast.");
return false;
}
},
"keypress #chat-message": function(e) {
if (Meteor.user() == null) {
alert("You must login to post");
return;
}
if (e.which == 13) {
//Validation
var bot =Check_bots();
if(bot==false)
{
$('#messages').animate({"scrollTop": $('#messages')[0].scrollHeight}, "fast");
console.log("you pressed enter");
e.preventDefault();
//repeat function from #send click event here
var message = $('#chat-message').val();
// check to see if the message has any characters in it
if (message.length < 1) {
alert("You must enter a message to post.");
return;
}
if (message.length > 200) {
alert("Your message is too long... they can't read that fast!");
return;
}
chatCollection.insert({
userId: 'me',
message: message
});
$('#chat-message').val('');
//add the message to the stream
chatStream.emit('chat', message);
}
else
{
alert("Slow down! No need to post that fast.");
return false;
}
}
}
});
chatStream.on('chat', function(message) {
chatCollection.insert({
userId: this.userId,
subscriptionId: this.subscriptionId,
message: message
});
});
var lastintime=0;
var defference=0;
var msg_count=0;
function Check_bots()
{
var seconds = new Date().getTime() / 1000;
seconds=parseInt(seconds);
if(lastintime < seconds)
{
defference = seconds -lastintime;
lastintime=seconds;
if(defference<=5 && msg_count>=3)
{
return true;
}
else
{
return false;
}
}
}
users.js:
Accounts.ui.config({
passwordSignupFields: "USERNAME_ONLY"
});
getUsername = function(id) {
Meteor.subscribe('user-info', id);
Deps.autorun(function() {
var user = Meteor.users.findOne(id);
if(user) {
Session.set('user-' + id, user.username);
}
});
}
Does anybody know a way to do this?
You could use Accounts.validateLoginAttempt
Server side code
Accounts.validateLoginAttempt(function(info) {
var user = info.user;
if(user.isBanned) throw new Meteor.Error(403, 'You are banned');
});
With the above code: If you added isBanned: true to any user in your MongoDB database, that user would not be able to sign in.

Categories

Resources