jQuery and Mysidia: A struggle

Forum
Last Post
Threads / Messages

IntoRain

Moderator
Moderator
Joined
Jul 31, 2013
Messages
459
Points
0
Location
Portugal
Mysidian Dollar
16,687
I know well that mysidia is anti-javascript currently, specially ajax, due to the way the pages are rendered. However, I started this and I really want to find a way.

So in my little test site for 1.3.4, I've been trying to use ajax to check if the username and e-mail already exists and tell the user real-time. I've accomplished this somewhat, but I came across two problems:

1) The function I'm using to verify the variables sent by the ajax request (for example, username and email) became a page itself (since most .php files and their respective functions are converted to html), like so http://website.com/register/checkusernamefunction. lol
To avoid this (access from users to pages that shouldn't be pages), I throw an error if the variable through post is empty (if username has no value). Which is kind of not a good way to do it... Is there a way to correct this? Maybe stop the page from rendering automatically?

2) I'm doing the verification of the word I write in the input field for each key press

PHP:
$('input#username').keyup(function(){})

but sometimes it seems it won't keep up. I made it display the .val() of the field and my results were: Like it will keep changing between the full word I wrote and part of the word or just display half the word. I think it's because of the delay of having to query the database for each key press or something that causes it to spazz. I'm honestly thinking of creating a buffer for this, lol
I tried using keydown and it stays behind one character for some reason (if I write "SampleAccount2" it will assume I wrote "SampleAccount", which is not as random as keypress or keyup).
Instead of each key press, I thought to use it with each click on the field, but it's kinda impractical for the users, since they have to click to write the username and then click outside the input field and then click the input again to check if it's being used.
I'm quite a newbie at this jquery thing, so I'm asking if these are the best ways to do it or if there are alternatives.

Also another thing. My question is: is it bad practice to have the script functions displayed on the page directly instead of having them all in a single file .js? I'm echoing the javascript I need in each page since including the file didn't seem to work
 
I've had my thoughts on a verification system for a while, too, but the way pages are rendered definitely does step in the way. I've made an ajax verification system before, not for Mysidia, of course, so I may attempt to hack it in somehow. I'll be sure and post the results someplace.

(Whether or not it's bad practice to or not to have a separate file comes down to a variety of things. I'd think of it like css. Sometimes you may need to do a little inline styling and that's fine, especially if it's only ever going to be used on that one thing. I'd say it's definitely useless to include anything on every single page if its not actively being used on it, but again, the way pages are rendered right now makes that hard. You could probably echo in a <script> only where it's used, but depending on what it is, you may need to creatively queue the script to only run after the page, and jQuery, has loaded.)

As for what you're doing here and now with the keyup and such... I'd personally recommend only checking the database once the input box as lost focus and they've tabbed or clicked away...? I think that's how I did it...?

Good luck, though. I'll try my hand at it, but probably in a week or two. I've got some other commitments right now.
 
Thank you! When you get to it it will be lovely if you can share the results ^^ I will share mine if I can put it to work and fix these annoyances. Or maybe I can post what I already have and maybe we can fix it somehow when you have time?

I tried the onblur() thing, but it didn't seem to do anything xD I will investigate on how to use it. Makes sense to only avaliate the full word after clicking away or tabbing

(and thank you, I agree on that xD I will keep echo'ing then, I don't know how much javascript I will need - I will probably only have that stuff in the register page plus in another page, so there's really no need to include it everywhere I guess)

---------------------------------------------------------

So with tabbing, it seems to work perfectly. With anything else like clicking outside it keeps spazzing out: Without me doing anything it will keep reading the full word, then half the word, then just one letter lol xD
The current code is like this:

PHP:
$(document).ready(function(){
				var ready = 0;				
				$('input#username').keydown(function(e){
				$('.div07').html('<i>Loading...</i>');	
				var key = e.which;
				var username = $(this).val();
				if(key == 9)
				{
					$.post('/register/checkusername', {username:username},function(result) {
			        	if(ready == 0){ if(result[0] != '0'){
			        		$('.div07').html('<i>Username is empty or is already being used:</i>' + username)}
			        	else{
			        	$('.div07').html('<i>Username can be used:</i>' + username)}
			        	}});					
				}
				else{
					$('input#username').focus(function(){
					//var username = $(this).val();
					});
					$('input#username').focusout(function(){
						username = $(this).val();
						$.post('/register/checkusername', {username:username},function(result) {
				        	if(ready == 0){ if(result[0] != '0'){
				        		$('.div07').html('<i>Username is empty or is already being used:</i>' + username)}
				        	else{
				        	$('.div07').html('<i>Username can be used:</i>' + username)}
				        	}});	
					});
				}
				});})

This seems to somewhat work (with the focus and tabbing you recommended!) Thank you!
 
Last edited:
Ok, well, on my test (unrelated to Mysidia):
Code:
<script>
 window.initQueue.push(function(){
	 $("#regusername").focus(function() {
	 $("label[for=regusername]").addClass('error').removeClass('success').removeClass('valid').text('');	 
	 });
	 $("#regusername").focusout(function() {
		 $("label[for=regusername]").addClass('error').removeClass('success').removeClass('valid').text('');	 
	 });
	$("#regusername").focusin(function() {
		$("#message").text("").css({'display' : 'none'});
	});
    $("#regusername").change(function(){
	$("#message").html("Checking...");
	var username=$("#regusername").val();
	 $.ajax({
		type:"post",
		url:"./assets/php/check.php",
		data:"username="+username,
		success:function(data){
			if(data==0){ $("#message").text("Username available!").css({'display' : 'none', 'color' : 'green', 'font-size' : '.8em', 'padding' : '2px 8px', 'margin-top' : '2px'}); }
			else{ $("#message").text("Username already taken!").css({'display' : 'inline-block', 'color' : 'red', 'font-size' : '.8em', 'padding' : '2px 8px', 'margin-top' : '2px'});
				  $("label[for=regusername]").addClass('error').removeClass('success').removeClass('valid').text('');}
			}
		});
	});
});
</script>

I'm using ajax there to push the result from my check.php (which I'd have to reconfigure to work with Mysidia, how do you have yours set up? Save me some some thinking?):
Code:
<?
 
  mysql_connect("127.0.0.1","root","");
  mysql_select_db("test");
 
  $username=$_POST["username"];
  $query=mysql_query("SELECT * from users where Username='$username' ");
 
  $find=mysql_num_rows($query);
 
  echo $find;
 
?>

I'd definitely read up on $.ajax?

You can safely ignore all the adding and removing of success/valid/error classes I did (because I was combining it with another system that also checked for minimum/maximum length requirements... and that passwords had a number, matched, and emails had an @). I was using the same span for both types of confirmation of success and if one was true but not the other, the whole span needed to be red. (ie: Yeah, it fits the minimum requirements for length, but it's taken so it needs to be red and throw and error, not have the green success check.)
 
Last edited:
Well seems that a lot of you are struggling with javascript in Mysidia, particulally AJAX. I will try to make the GUI system better at handling javascript in Mys v1.4.0 so you can add javascript events like onclick, onkeypress easily. Not sure how much this will help though, but at least its some kind of improvements I can offer.
 

I didn't use $.ajax because $.post did the same in one line (I believe it's ajax too?), first is the url of the file, second is the data and third is the function that works the results. At least that's what I understood xD

Aah thanks for sharing! I will try to use all the .focus and .change functions to see if it corrects the spazzing that happens sometimes

There's a few issues with mysidia's pages, so I kinda went around the problems lol For example the php spits out errors in the result of the ajax request if the document isn't created and doesn't have a title, so you have to create it as a page. Because my function turns into a page itself, that means users can access it, so I made it throw exceptions if the the value recieved is null.

Then if the function is fine, the result spits out the full page's html xD I went around this by accessing the characters of the result (since it ends up being a string). So if the php echos 0 as result, the result will be a string with 0 followed by the predefined html of the page. So result[0] is the first element of that string and the result I actually want (that's why I compare result[0] and not result)

It's a very... sloppy way of going around it. And maybe it's what causes the spazzing by making it slow down, no idea xD I will try again with other ways soon enough x.x Anyway, I added this function to register.php page: (hopefully it's useful)

PHP:
public function checkusername(){
	$mysidia = Registry::get("mysidia");

	if($mysidia->input->post("username") == NULL)//works as $_POST[]
	{
		throw new NoPermissionException("You specified an invalid action that cannot be completed.");
	}
		$document = $mysidia->frame->getDocument();	
		$document->setTitle("error");
		$username = $mysidia->input->post('username');
		$count = $mysidia->db->select("users",array("uid"),"username = '{$username}' LIMIT 1")->rowCount();//database query
		echo $count;//result
	}

The javascript part is in registerview.php and is like what I wrote before ^^ (this is because apparently I need to put the php function inside a controller (register.php is the controller for the register page) if I want to use the url like 'page/function ' instead of 'page.php'. I tried creating a new blank page and use it like page.php but it gave out many errors)

Well seems that a lot of you are struggling with javascript in Mysidia, particulally AJAX. I will try to make the GUI system better at handling javascript in Mys v1.4.0 so you can add javascript events like onclick, onkeypress easily. Not sure how much this will help though, but at least its some kind of improvements I can offer.

That would be pretty cool! Thank you! These verifications I don't really need to do them with javascript, but it makes the website look so much cleaner and gives us room for so many effects xD

----

OOOH I was checking the focus thing after a key press, I think that's why it spazzed! The code is now (I made it a function since I will use it for email as well):

PHP:
<script>

/**
*Recieves a string as input and depending on the type, makes the necessary
*verifications
*/
function checkinput(input, type){
		
				switch(type){
					case 1://for username
						if(input.length > 20)
						{
							$('.div07').html('<i>Username has too many characters:</i>' + input);
                                                         return;
						}//regex missing

						$.post('/register/checkusername', {username:input},function(result) {
							if(result[0] != '0'){
								$('.div07').html('<i>Username is empty or is already being used:</i>' + input)
							}
							else
							{
								$('.div07').html('<i>Username can be used:</i>' + input)
							}
						});
						return 0;						
						break;
					case 2://for email
						
						break;
					default:
						break;
					}
			}
								
			$(document).ready(function(){
				var ready = 0;				
				$('input#username').keydown(function(e){
				$('.div07').html('<i>Loading...</i>');	
				});
				//var key = e.which;
				var username = $(this).val();
					$('input#username').focusin(function(){
					username = $(this).val();
					});
					$('input#username').focusout(function(){
						username = $(this).val();
						checkinput(username,1);	
					});
				
				})
			</script>

I believe it is working properly now: http://stareach.x10.mx/register (this is my test site for 1.3.4 so no registration actually exists xD - but you can test the username input thing). It checks the name whe nthe box loses focus (when you click somewhere else), you can use TestAccount to check the already exists error
 
Last edited:
Nice! Will you go forth and make an official mod thread for this? I think it's a rather in-demand feature.
 
Yeah, I think! I was finishing the verifications of the stuff I wanted in the registration page before putting it up - I think it's done (can be tested in the same link)

-> Verifies Username and password size
-> Verifies Username, e-mail and date format
-> Verifiies existence of Username and e-mail in database

I will still clean it up somewhat tomorrow and then write a mini guide for it. Not sure if this should be a mod or just a tutorial?

The problem with the php spitting the full html as response plus turning the php into a page itself automatially still stands - I've avoided these problems, not solved them, which is kinda sucky xDD
 
In trying to do this myself, I've run across a lot of problems. How're your register and registerview pages set up now, in full?

Also, for the fun of it, this may interest you:
Code:
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.11.1/jquery.validate.min.js"></script>
<script>
/* FORM VALIDATION */
$("#regform").validate( { 
rules: { 
	username: { minlength: 2, maxlength: 20, required: true },
	email: { required: true, email: true },
	pass1: { minlength: 7, maxlength: 20, required: true },
	pass2: { equalTo: "#pass1" } },
success: function(element) { $(element).text("OK!").closest("input") } 
});
</script>

Documentation for this plugin can be found here.
 
That looks interesting yes, quite nice o.o I will try to incorporate it somehow xD

What errors are you getting? I had troubles when I accidentely closed the Comment field, so the script wouldn't even run and I didn't understand why lol If there's a little small error somewhere in the javascript, no script will run. For example I was trying to use <font color> and since it was deprecated it made the script not run at all

register.php:
PHP:
<?php

use Resource\Native\String;
use Resource\Collection\HashMap;

class RegisterController extends AppController{
	
    public function __construct(){
        parent::__construct("guest");
    }
	
		public function checkusername(){
	$mysidia = Registry::get("mysidia");
	if($mysidia->input->post("username") == NULL)
	{
		throw new NoPermissionException("You specified an invalid action that cannot be completed.");
	}
		$document = $mysidia->frame->getDocument();	
		$document->setTitle("error");
		$username = $mysidia->input->post('username');
		$count = $mysidia->db->select("users",array("uid"),"username = '{$username}' LIMIT 1")->rowCount();
		echo $count;
	}
	
	public function checkemail(){
	$mysidia = Registry::get("mysidia");
	if($mysidia->input->post("email") === NULL)
	{
		throw new NoPermissionException("You specified an invalid action that cannot be completed.");
	}
		$document = $mysidia->frame->getDocument();
		$document->setTitle("error");
		$email = $mysidia->input->post("email");
		$count = $mysidia->db->select("users",array("uid"),"email = '{$email}' LIMIT 1")->rowCount();
		echo $count;
	}
	
	public function index(){
	    $mysidia = Registry::get("mysidia");		
	    if($mysidia->input->post("submit")){
	    	throw new NoPermissionException("No registrations please");
		    $mysidia->session->validate("register");	
            $validinput = array("username" => $mysidia->input->post("username"), "password" => $mysidia->input->post("pass1"), "email" => $mysidia->input->post("email"), "birthday" => $mysidia->input->post("birthday"), 
                                "ip" => $mysidia->input->post("ip"), "answer" => $mysidia->input->post("answer"), "tos" => $mysidia->input->post("tos"));
            $validator = new RegisterValidator($mysidia->user, $validinput);
            $validator->validate();
  
            if(!$validator->triggererror()){
	            $mysidia->user->register();	
				include("inc/config_forums.php");
	            if($mybbenabled == 1){
                    include_once("functions/functions_forums.php");   
                    mybbregister();
                    mybbrebuildstats();
                }
	            $mysidia->user->login($mysidia->input->post("username"));
            }
            else throw new RegisterException($validator->triggererror());  
			$mysidia->session->terminate("register");
			return;
		}
		$mysidia->session->assign("register", 1, TRUE);		
	}              
}
?>
registerview.php:
PHP:
<?php
	
class RegisterView extends View{
	

	public function index(){
	    $mysidia = Registry::get("mysidia");
		$document = $this->document;		
	    if($mysidia->input->post("submit")){
		    $document->setTitle($this->lang->success_title);
            $document->addLangvar($this->lang->success.$mysidia->input->post("username").$this->lang->success2);	
			return;
		}

        $document->setTitle($this->lang->title);
        	
        $document->addLangvar($this->lang->default);		
		$registerForm = new Form("regform", "", "post");

		$registerDiv = new Comment("<div class='div07'>");
		$registerDiv1 = new Comment("</div>");
		$requiredField = new FieldSet("required");
		$requiredField->add(new Legend("Required Info"));
		$requiredField->add(new Comment("
			<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
			<script>
			function checkinput(input, type){
		
				switch(type){
					case 1://username
						var res = input.match(/^[a-zA-Z0-9][a-zA-Z0-9\s]{1,18}[a-zA-Z0-9]$/);
						if(input.length > 20)
						{
							$('.divUsername').html('<i>Username has too many characters:</i>' + input);
							return;
						}
						if(res == null)
						{
						     $('.divUsername').html('<i>Username can only contain letters, numbers and spaces:</i>' + input);
							return;
						}
						$.post('/register/checkusername', {username:input},function(result) {
							if(result[0] != '0'){
								$('.divUsername').html('<i>Username is empty or is already being used:</i>' + input)
							}
							else
							{
								$('.divUsername').html('<i>Username can be used:</i>' + input)
							}
						});
						return 0;						
						break;
					case 2:
						var res = input.match(/^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,4}$/);
						if(res == null)
						{
							$('.divEmail').html('<i>E-mail is not in the correct format: </i>' + input);
							return;
						}
						$.post('/register/checkemail', {email:input},function(result) {
							if(result[0] != '0')
							{
								$('.divEmail').html('<i>E-mail is empty or is already being used:</i>' + input);
							}
							else
							{
								$('.divEmail').html('<i>E-mail can be used:</i>' + input);
							}
						});
						break;
					case 3:
						var res = input.match(/^\d{2}\/\d{2}\/\d{4}$/);
						if(res == null)
						{
							$('.divBirthday').html('<i>Birthday is not in the correct format:</i>' + input);
							return;
						}
						else
						{
							$('.divBirthday').html('<i>Birthday is in the correct format and can be used:</i>' + input);
							return;
						}
						break;
					case 0:
						if(input.length <= 0 || input.length > 20)
						{
							$('.divPassword').html('<i>Password is not the correct size (either empty or bigger than 20 characters)</i>');
							return;
						}
						else
						{
							$('.divPassword').html('<i>Password is in the correct format and can be used</i>');
							return;
						}
						break;
					
					default:
						break;
					}
			}
								
			$(document).ready(function(){	
			//alert('hey');	
				$('input#username').keydown(function(e){
				$('.divUsername').html('<i>Loading...</i>');	
				});
				$('input#email').keydown(function(e){
				$('.divEmail').html('<i>Loading...</i>');	
				});
				$('input#pass1').keydown(function(e){
				$('.divPassword').html('<i>Loading...</i>');
				});
				$('input#birthday').keydown(function(e){
				$('.divBirthday').html('<i>Loading...</i>');
				});	
				
					$('input#username').focusout(function(){
						username = $(this).val();
						checkinput(username,1);							
					});
					$('input#email').focusout(function(){
						var email = $(this).val();
						checkinput(email,2);
					});
					$('input#pass1').focusout(function(){
						var pass = $(this).val();
						checkinput(pass,0);
					});
					$('input#birthday').focusout(function(){
						var birthday = $(this).val();
						checkinput(birthday,3);
					});
				
				})
			</script>
			
		",FALSE));		
		$requiredField->add(new Comment("Username: ", FALSE, "b"));
        $requiredField->add(new Comment("Your username may be up to 20 characters long with letters, numbers and spaces only.",FALSE));
        $requiredField->add(new TextField("username")); 
       $requiredField->add(new Comment("<div class='divUsername'></div>",FALSE));//USERNAME DIV ADD THIS LINE
        
        $requiredField->add(new Comment("Password: ", FALSE, "b"));
        $requiredField->add(new Comment("Your password may be up to 20 characters long and may contain letters, numbers, spaces and special characters. The use of a special character, such as * or ! is recommended for increased security. "));
        $requiredField->add(new Comment("Enter Password ", FALSE));
		$requiredField->add(new PasswordField("password", "pass1", "", FALSE));
        $requiredField->add(new Comment(" Confirm Password ", FALSE));
        $requiredField->add(new PasswordField("password", "pass2", "", TRUE));
        $requiredField->add(new Comment("<div class='divPassword'></div>",FALSE));
        $requiredField->add(new Comment("Email Address: ", FALSE, "b"));
        $requiredField->add(new Comment("Enter a valid email address for yourself."));
        $requiredField->add(new PasswordField("email", "email", "", TRUE));
       	$requiredField->add(new Comment("<div class='divEmail'></div>",FALSE));
        $registerForm->add($requiredField);

        $additionalField = new FieldSet("additional");
        $additionalField->add(new Legend("Additional Info"));
        $additionalField->add(new Comment("Birthday: ", FALSE, "b"));
        $additionalField->add(new Comment("(mm/dd/yyyy)"));	
        $additionalField->add(new TextField("birthday"));
        $additionalField->add(new Comment("<div class='divBirthday'></div>",FALSE));
		$additionalField->add(new Comment("Avatar: ", FALSE, "b"));
        $additionalField->add(new Comment("Enter the url of your avatar beginning with http://www."));	
        $additionalField->add(new TextField("avatar", "templates/icons/default_avatar.gif"));
		$additionalField->add(new Comment("Nickname: ", FALSE, "b"));
        $additionalField->add(new Comment("A nickname for yourself, do not use inappropriate words! "));	
        $additionalField->add(new TextField("nickname"));
		$additionalField->add(new Comment("Gender: ", FALSE, "b"));
        $additionalField->add(new Comment("Male, Female or Not specified"));

        $genderList = new RadioList("gender");	
		$genderList->add(new RadioButton("Male", "gender", "male"));
        $genderList->add(new RadioButton("Female", "gender", "female"));
        $genderList->add(new RadioButton("Unknown", "gender", "unknown"));
        $genderList->check("unknown");
        $additionalField->add($genderList);

		$additionalField->add(new Comment("Favorite Color: ", FALSE, "b"));
        $additionalField->add(new Comment("Your favorite color. Red, Yellow, Blue, who knows? "));	
        $additionalField->add(new TextField("color"));
		$additionalField->add(new Comment("Biography: ", FALSE, "b"));
        $additionalField->add(new Comment("Enter a bio for yourself, if you want to."));	
        $additionalField->add(new TextArea("bio", "", 4, 50));
		$registerForm->add($additionalField);
		
		$securityField = new FieldSet("security");
		$securityField->add(new Legend("Anti-Spam Security Question"));
		$securityField->add(new Comment("Question: ", FALSE, "b"));
		$securityField->add(new Comment($mysidia->settings->securityquestion));
		$securityField->add(new Comment("Answer: ", FALSE, "b"));
		$securityField->add(new TextField("answer"));
		$securityField->add(new CheckBox("I agree to the <a href='tos' target='_blank'>Terms of Service", "tos", "yes"));
		$securityField->add(new PasswordField("hidden", "ip", $_SERVER['REMOTE_ADDR'], TRUE));
		$securityField->add(new Button("Register", "submit", "submit"));
		$registerForm->add($securityField);
		$document->add($registerForm);
	}              
}
?>
 
Partly, I was curious to see how you made the modifications. But my problem is that it's stuck on 'Loading...'.
 
Mine would get stuck on loading if I had an error afterwards. Try commenting everything and uncomment lines slowly? I used alert('') to check if it reached certain parts (also to output values to see if they were correct)

Or is it getting stuck anyway with my code like that? x.x I think regex made the page slower the first time I used it, so it would take a while to calculate the result
 
Last edited:

Similar threads

Users who are viewing this thread

  • Forum Contains New Posts
  • Forum Contains No New Posts

Forum statistics

Threads
4,280
Messages
33,130
Members
1,603
Latest member
Monako
BETA

Latest Threads

Latest Posts

Top