Ok so i have a Chatroom, People are required to type in a name and once done they may chat. But alot of times people take other peoples name. So what i need is kind of like a limited input
here is the input:
<input type="text" class="input-block-level" ng-model="name" ng-change="setName()" placeholder="Your Name" maxlength="10" required></div>
I need this so if i type in the name Bob, no one can use that name again
Incase you want the website: https://project-js-imthatguy.c9users.io/
One possible way to check amongst a given set...
used a simple for loop for this example
Inside your send function that you have defined, perform a check:
$scope.send = function send() {
var isDuplicated = 0
for (i = 0; i < $scope.roster.length; i++){
if ($scope.roster[i] == $scope.name){ isDuplicated++ }
}
if (isDuplicated > 1){
//make an error message appear here
//quick and dirty solution
alert('Please choose a name that has not been taken by someone else')
//suggestion set a variable here to true and then use that variable to show/hide a div below the user input area
}
else {
console.log('Sending message:', $scope.text);
socket.emit('message', $scope.text);
$scope.text = '';
}
};
Related
I have an input field in which I want first 4 characters to be numbers only, after that only dot(.) is allowed, and then only 2 numbers allowed. Example: 9999.99
I also want that if I am entering something else it should not enter in input field.
For this I created a regex as : ^[0-9]{4}+\.+[0-9]{2}+$
HTML: <input type="text" (keypress)="onKeydown($event)">
TS:
regex = '/^[0-9]{4}+\.+[0-9]{2}+$/';
onKeydown(event) {
if(event.target.value.match(this.regex)) {
return true;
} else return false;
}
But I guess I am doing something quite wrong here. Kindly let me know about it.
Thanks.
You don't need + (select 1 or more matches) in your regex.
Instead, you need | (or) to catch two cases: when input does not contain dot and when dot is added.
Try something like this: /^(?:\d{0,4}|\d{4}\.\d{0,2})$/.
I've added ?: (non-capturing group mark) to exclude group in match, but it's not necessary.
UPDATE: here's a quick sketch using oninput event handler:
var regex = /^(?:\d{0,4}|\d{4}\.\d{0,2})$/;
var lastValue = "";
function onInput(e) {
var currentValue = e.target.value;
if (!currentValue.match(regex))
e.target.value = lastValue;
else
lastValue = currentValue;
}
<input type="text" oninput="onInput(event)">
I have made validation in input field in html5 to get this format 03xx-xxxxxxx.
pattern="03\d{2}-\d{7}"
Now I want to add this hyphen symbol automatically after fourth digit.How to do that?
I must advice you against this type of input edit since it's usually frustrating when you need to edit typos.
Also I have no idea of the issues related to accessibility.
The input pattern only checks the data on submit, so it's not what you are looking for.
That said, here's one possible solution in JS:
// select the input element
var i = document.querySelector('input.hyphen');
// number of charatcers before the hyphen
var n = 4;
// run this function everytime the user release a key
i.addEventListener('keyup', function (event) {
// if there are more then n digits
if (i.value.length > n) {
// save the carret position
var s = i.selectionStart;
// remove all dashes
var t = i.value.replace(/-/g, '');
// beginning string with n digits
var b = t.substr(0, n);
// end string with what's left (maxLength)
var e = t.substr(n);
// join then with a dash
i.value = [b, e].join('-');
// if the caret was before the dash put it back to the saved position
if (s <= n) i.setSelectionRange(s, s);
// if the caret was next to the dash put it after
if (s == n+1) i.setSelectionRange(s+1, s+1);
}
});
<input class="hyphen" placeholder="0000-0000000" maxlength="12">
I have made validation in input field in html5 to get this format 03xx-xxxxxxx.
One alternative approach (without javascript) is to use three <input /> fields.
Working Example:
#country,
#region {
width: 16px;
}
#local {
width: 56px;
}
<input type="text" id="country" value="03" readonly />
<input type="text" id="region" pattern="[0-9]{2}" placeholder="88" />
-
<input type="text" id="local" pattern="[0-9]{7}" placeholder="8888888"/>
So I have a University assignment where I must have authenticated users login to edit a text file. I'm trying to contain this all within the one CGI file to keep it easy.
I've written a html form as shown below:
Admin Login:
<form name="login" method="post" action="pbr.cgi"><input type="text" name="user" value="Username" onfocus="(this.value == 'Username') && (this.value = '')"onblur="(this.value == '') && (this.value = 'Username')"/>
<input type="password" name="password" value="123456" onfocus="(this.value == '123456') && (this.value = '')"onblur="(this.value == '') && (this.value = '123456')"/>
<input class="login" name="Login" type="submit" value="Login"></form>
I also have a login sub in the cgi as below:
sub Login {
$luser = $cgi->param('user');
$lpass = $cgi->param('password');
open (PASSWD, "<passwords.txt");
my #passwds = <PASSWD>;
close (PASSWD);
foreach (#passwds){
($user, $pass, $passsalt) = split ":";
if ($user = $luser){
$testpass = $salt . $lpass;
$testpass = sha256_hex($testpass);
if ($pass = $testpass){
$validuser = 1;
} else {
$validuser = 0;
}
} else {
print "Failure!"
}
}
}
Can someone explain to me how I get the CGI to recognise the login button has been pressed and subsequently execute the Login sub while reloading the page? Obviously I'll have to set a cookie as well once I get this working but I just want to get it working first.
The CGI module you're (obviously) using also supports fetching the parameter list as a hash. You should try to dump this out to the see complete request:
print Dumper($cgi->Vars);
You'll notice that the Login button is a <input ...> tag like the others and behaves exactly the same way: By setting a parameter defined by the name= and value= properties.
Three additional remarks on your script:
if ($user = $luser){ says: Try to copy the value of $luser into the variable $user. If this succeeds and the new value of $user is true (not undef, empty or 0), run the following lines until end of the if block. = is an assignment in Perl, while == and eq are comparisons. See http://perldoc.perl.org/perlop.html#Equality-Operators for more information.
The better way of reading a file is using while (<FILEHANDLE>) { ... }. Your solution read the full file into memory even if the first line matches the user trying to login. while reads line-by-line until you exit the loop.
Consider running PerlCritic on your sourcecode. It doesn't check for errors, but shows best practice hints where the Perl community prefers some other way. Don't try to "fix" every critic report, but check them to improve your code.
I implemented an advance search with 15 input fields in AngularJS.
In the page load itself the result set is return from database in JSON format and i need to do the filter in client side only.
The input criteria's equivalent column is available in the result set and i need to check in its respective column only.
I am converting each column by JSON.stringify() and check with the search params like the below :
$scope.filteredData = $scope.actualData.filter(function(item) {
return JSON.stringify(item.FirstName).toLowerCase().indexOf(lowerFirstName) != -1 &&
JSON.stringify(item.LastName).toLowerCase().indexOf(lowerLastName) != -1 &&
JSON.stringify(item.EmailAddress).toLowerCase().indexOf(lowerEmailAddress) != -1 &&
JSON.stringify(item.Address1).toLowerCase().indexOf(lowerAddress1) != -1 &&
JSON.stringify(item.Address2).toLowerCase().indexOf(lowerAddress2) != -1;
...... etc // upto 15 fields
});
Since i have the 15 input fields and the actual result set contains a minimum of 50,000 records.
So converting each record's each column by JSON.stringify() and check with search params will surely cause the performance issue.
Is there any other way to achieve the filtering in client side with other approach.
I posted a sample code in Plunker with 5 input fields only : http://plnkr.co/edit/nUWZEbGvz7HG6gb91YZP
sylwester's answer is the normal way you'd filter things. Your code looks like you want to filter down to only the object that matches every input field. You code attempts to find an object where every property matches the searchParams object. At that point, I don't see what benefit there is to finding that object, because the user already created the object again! Nonetheless, here's a proper version of your code:
Live demo here.
<div ng-repeat="data in actualData | filter:searchData()">
$scope.searchData = function() {
return function(item) {
return Object.keys(item).every(function(key) {
// skip the $$hashKey property Angular adds to objects
if (key === '$$hashKey') { return true; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
return item[key].toLowerCase() === $scope.searchParams[searchKey].toLowerCase();
});
};
};
You really need to limit the data coming from the server for the browser's sake and for the server's sake. It's easy to implement a LIMIT, OFFSET system. It sounds like, overall, you just need to be able to query the server for a certain record.
From your comments, it seems you definitely want Angular's built in filter filter:searchParams, and just capitalize your searchParams models to match your data. For fun, I'll include more options for finer tuning.
This one almost mimics filter:searchParams. You can change > 1 to adjust when the partial matching kicks in, or have it return true only when both items are strictly equal === to disable partial matching. The difference here is that all items are hidden until matched, whereas filter:searchParams will show all items and then remove what doesn't match.
Live demo here.
$scope.searchData = function() {
return function(item) {
return Object.keys(item).some(function(key) {
if (key === '$$hashKey') { return false; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
var currentVal = $scope.searchParams[searchKey].toLowerCase();
var match = item[key].toLowerCase().match(currentVal);
return currentVal.length > 1 && match;
});
};
};
Lastly, to perfectly mimic filter:searchParams, you'd just put in a check to NOT filter the items until there is user input and the input is long enough to start the partial match.
Live demo here.
$scope.searchData = function() {
var partialMatchLength = 2;
return function(item) {
var shouldFilter = Object.keys($scope.searchParams).some(function(key) {
return $scope.searchParams[key] && $scope.searchParams[key].length >= partialMatchLength;
});
if (!shouldFilter) { return true; }
return Object.keys(item).some(function(key) {
if (key === '$$hashKey') { return false; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
var currentVal = $scope.searchParams[searchKey].toLowerCase();
var match = item[key].toLowerCase().match(currentVal);
return currentVal.length >= partialMatchLength && match;
});
};
};
First of all you ng-repeter with 50.000 records more likely is going to kill your browser, so you should thing about pagination.
Secondly you can easy filter your data using angular filter please see that demo
http://plnkr.co/edit/R8b8G4xCMSQmX1144UJG?p=preview
<div ng-controller="ListCtrl">
<br />
First Name:
<input type="text" id="txtFirstname" ng-model="searchParams.FirstName">
<br/>Last Name:
<input type="text" id="txtLastname" ng-model="searchParams.LastName">
<br/>Email Address:
<input type="text" id="txtEmailAddress" ng-model="searchParams.EmailAddress">
<br/>Address 1:
<input type="text" id="txtAddress1" ng-model="searchParams.Address1">
<br/>Address 2:
<input type="text" id="txtAddress2" ng-model="searchParams.Address2">
<br/>
<button class="btn btn-primary" ng-click="searchData()">Search</button>
<br />
<hr />
<b>Filtered Data(s):</b>
<div ng-repeat="data in actualData | filter:searchParams ">
<span ng-bind="data.FirstName"></span>
<span ng-bind="data.LastName"></span> |
Address : {{data.Address1}}
</div>
<hr />
</div>
What I want to happen with the following code is when a user checks multiple data centers and then selects a type of change it will automatically refresh the description and Impact text area with a unique string statement including the data centers the user has chosen.
Can someone advise me what I am doing wrong?
JS:
function updateDescImpact() {
var changeSel = document.changeform.change_type;
var ChangeType = (changeSel.options[changeSel.selectedIndex].value);
var description = " ";
var impact = " ";
var data_center = "";
var inputs = document.getElementsByTagName('input');
for (var x = 0; x < inputs.length; x++) {
{
if (inputs[x].type == "checkbox" && inputs[x].name == 'data_center[]') {
if (inputs[x].checked == true) {
data_center += inputs[x].value + ',';
}
}
}
if (/,$/.test(data_center)) {
data_center = date_center.replace(/,$/, "")
}
if (ChangeType == "Filer Changes") {
description = "This is the Filer Change Description for $('data_center')";
impact = "This is the Filer Changes impact statement for $('data_center')";
} else if (ChangeType == "DNS Changes") {
description = "This is the DNS Change Description for $('data_center')";
impact = "This is the DNS Changes impact statement for $('data_center')";
} else {
description = "";
impact = "";
}
document.changeform.description.value = description;
document.changeform.impact.value = impact;
}
HTML:
<form action="" id="changeform" method="post" name="changeform">
<input type="submit" value="submit change">
<table>
<tr valign="top">
<td><strong>Data Center</strong></td>
<td><input name="data_center[]" type="checkbox" value="zone1">Zone1
<input name="data_center[]" type="checkbox" value=
"Zone2">Zone2</td>
</tr>
<tr valign="top">
<td><strong>Change Type</strong></td>
<td><select id="change_type" name="change_type" onchange=
"updateDescImpact()">
<option value="DNS Changes">
DNS Changes
</option>
<option value="Filer Changes">
Filer Changes
</option>
</select></td>
</tr>
<tr valign="top">
<td><strong>Description</strong></td>
<td>
<textarea cols="50" id="description" name="description" rows="10">
This text needs to be updated
</textarea>
</td>
</tr>
<tr valign="top">
<td><strong>Service Impact</strong></td>
<td>
<textarea cols="50" id="impact" name="impact" rows="10">
This text needes to be updated
</textarea></td>
</tr>
</table>
</form>
With only a minimal idea of what it is you want to do with the string, once you've got it, I've put together the following:
function updateDescImpact() {
// declaring all the variables, separating them with commas, at once.
// retrieves the element:
var changeSel = document.getElementById('change_type'),
// defines the various default messages:
changes = {
'DNS': {
'impact': 'This is the DNS Change impact statement for $("data_centre")',
'description': 'This is the DNS Change Description for $("data_center")'
},
'Filer': {
'impact': 'This is the Filer Changes impact statement for $("data_centre")',
'description': 'This is the Filer Change Description for $("data_center")'
}
},
ChangeType = (changeSel.options[changeSel.selectedIndex].value),
// creates an array:
data_center = [],
inputs = document.getElementsByTagName('input');
for (var x = 0, len = inputs.length; x < len; x++) {
{
if (inputs[x].type == "checkbox" && inputs[x].name == 'data_center[]') {
if (inputs[x].checked === true) {
// adds the checkbox-values to the array:
data_center.push(inputs[x].value);
}
}
}
// creates another key for the 'changes' object,
// the value of which is determined by whether the array contains values,
// if it *does*, then those values are joined together using the given string,
// if *not*, then the value is an empty string.
// in both cases the value is followed by a period.
changes.data_centers = (data_center.length > 0 ? ': ' + data_center.join(', ') : '') + '.';
document.getElementById('description').value = changes[ChangeType].description + changes.data_centers;
document.getElementById('impact').value = changes[ChangeType].impact + changes.data_centers;
}
}
JS Fiddle demo.
In the next part I'll try to explain the changes I've made, but the simple, central, premise is to minimise the amount of work you're doing, and to reduce the scope for errors to creep in.
Where you were using:
document.changeform.change_type;
I've chosen, instead, to use:
var changeSel = document.getElementById('change_type');
This is because using the id of the relevant element is faster than navigation through the DOM using two ids, especially since there's no guarantee that the element will be recognised by its id when it's used as a global variable without being declared. It works almost everywhere, yes, but it's not a standard, or specified, behaviour in JavaScript and was a convenience offered, initially, in Internet Explorer. This convenience is not guaranteed to present in future, however.
Also, an id is (and must be) unique within the document, therefore there's no sense in using two, when one will do perfectly well.
The use of an object to contain the various alternative strings you (might) want to use, this is to reduce the need for multiple if/else if/else statements. And makes it somewhat easier to update the function in future to address new options and requirements. As stated, above, this is to minimise the amount of work you have to do (now, and in the future).
Where you used:
if (/,$/.test(data_center)) {
data_center = date_center.replace(/,$/, "")
}
I chose, instead, to use an array:
data_center = [],
This allows us to avoid having to use regular expressions which, while in this case was simple enough, is not always the case and, again, is more difficult than necessary for the finished result. Whereas an array can use the .join() method (used later) which will join the array elements together with the defined string, and will not result in a trailing-comma.
I've also used getElementById() in the last two lines to assign the various strings/values to the relevant elements. For precisely the same reason as outlined above.