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
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();
}
}
});
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.
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.
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.
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.