Jump to content

Getting php to change the appearance of an html element


Arbu

Recommended Posts

You can set the action attribute of the form to point to the same page and then have PHP check for form data to determine when to change the content on the page.

Link to comment
Share on other sites

Thanks. If I do this does the whole page have to be refreshed? I have a web application and the user might create data on the page before logging in. He doesn't want to lose that when he logs in.

Link to comment
Share on other sites

PHP cannot operate without refreshing the page, but the data is sent to the server, so you can use that data to populate the form.

If you want to do operations without refreshing the page, you cannot use PHP, you will have to use Javascript.

Link to comment
Share on other sites

I don't mind using javascript. But if I understand correctly, an html form can only submit data by specification of a web page to be navigated to. That can be the current one, but it will be refreshed. 

The user's login details will have to be stored on the server. Why can I not simply send a request to the server and get a response without having to refresh the user's browser?

Link to comment
Share on other sites

OK, so I have two things that happen when the user clicks the OK button in my form. The form's data gets hashed and the user is logged in. I don't want any new page to be directed to so I remove the form's action setting (which called the log in procedure) and I remove the type="submit" property from the button's html. And I create a new function to call the hashing and logging in together. So my code is below. It's plainly not correct as it generates loads of errors. How do I call (a) a javascript function and (b) a php function from some html code which is within a php condition?

     <!--Login Modal-->
     <?php if (login_check($mysqli) == false) :  ?>
         <div id="loginform" data-iziModal-group="grupo1">
             <button data-iziModal-close class="icon-close">x</button>  
             <header>
             <a href="" id="signin">Sign in</a>
             </header>
             <section>
             <form method="post" name="login_form" id="login_form">
             <input type="text" placeholder="Email" name="email" class="login_email" id="login_email">
             <input id="password" type="password" placeholder="Password" name="password" class="login_password">
             <footer>
             <button data-iziModal-close>Cancel</button>
             <button class="submit" data-iziModal-close onclick="hashandlogin(this.form, this.form.password);">Log in</button>
             <p style="text-align: center; color: #444; font-size: 16px; font-family: Lato; padding-top: 70px; font-weight: 500;">
            Don't have an account? <a style="font-size: 16px; font-weight: 500; font-family: Lato;" href="register.php">Register here.</a></p>
                            </footer>
                            </form>
                        	</section>
                        </div>
				
			  <script type="text/javascript">
		function hashandlogin(a,b){
				formhash(a,b);
				include_once 'process_login.php';
				console.log(login_check($mysqli));
		}	
		</script>	
			<?php endif; ?>		

 

Link to comment
Share on other sites

You can't run php within javascript code unless its in php tags.

Php is run from server and returns textual  html and thats it!

What you see on page after page load is all you get from php at that point. Only by using AJAX where you send data through 'post' or 'get' to an external php page where it retrieves those values and creates the necessary html required will php be involved.

What you need to do is create the external php first, create the html content you want to insert, thats it!

On main page you need an event to be triggered either through a form, where the form uses onsubmit and will use preventDefault(); to stop form submitting the normal method where it causes page to reload, it will collect form input data and through ajax javascript, send to the external php page you just created and got to work hopefully and that is returned to originating page and read and displayed where you want through ajax javscript code.

Edited by dsonesuk
Link to comment
Share on other sites

OK, thanks. I understand what you are saying, but still this does seem inordinately difficult. What I suppose I must do is have a form that:

a) has a type =submit button,

b) does not have an action for the form, as I don't want a new page shown,

c) has preventDefault applied as I don't want the current page refreshed. Hopefully this will still cause the data to be submitted by the form (?),

d) calls an AJAX procedure to log in and get the info I need to set what I want on the page with javascript.

The first problem I am getting is that this still causes the page to refresh. Do I need to convert my php file to a function, and if so how? Here's my latest code:

 <?php if (login_check($mysqli) == false) :  ?>
         <div id="loginform" data-iziModal-group="grupo1">
             <button data-iziModal-close class="icon-close">x</button>  <!--watch out here - JSFormat formatted the izimodal spec to have spaces in it and the button no longer worked.-->
             <header>
             <a href="" id="signin">Sign in</a>
             </header>
             <section>
             <form method="post" name="login_form" id="login_form">
             <input type="text" placeholder="Email" name="email" class="login_email" id="login_email">
             <input id="password" type="password" placeholder="Password" name="password" class="login_password">
             <footer>
             <button data-iziModal-close>Cancel</button>
             <button class="submit" data-iziModal-close type="submit" onclick="hashandlogin(this.form, this.form.password);">Log in</button>
             <p style="text-align: center; color: #444; font-size: 16px; font-family: Lato; padding-top: 70px; font-weight: 500;">
            Don't have an account? <a style="font-size: 16px; font-weight: 500; font-family: Lato;" href="register.php">Register here.</a></p>
                            </footer>
                            </form>
                        	</section>
                        </div>
				
			  <script type="text/javascript">
			  
			  document.getElementById("login_form").addEventListener("submit", function (event) {
			      event.preventDefault()
			  });
			  
		function hashandlogin(a, b) {
		    formhash(a, b);
		    var xmlhttp = new XMLHttpRequest();
		    xmlhttp.onreadystatechange = function () {
		        if (this.readyState == 4 && this.status == 200) {
		            console.log("done");
		        }
		    };
		    xmlhttp.open("GET", "process_login.php", true);
		    xmlhttp.send();

		}
		</script>	
<?php

include_once 'db_connect.php';
include_once 'functions.php';

sec_session_start(); // Our custom secure way of starting a PHP session.

if (isset($_POST['email'], $_POST['p'])) {
    $email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
    $password = $_POST['p']; // The hashed password.

    if (login($email, $password, $mysqli) == true) {
        $_SESSION["email"] = $email;
        saveLogin($_SESSION['user_id'],$mysqli);
		echo ("something");
        // Login success
      //  header("Location: ../account.php");  I don't want the account page shown just cos user has logged in. But what should go here? If nothing or index.php then get a blank page with process_login.php as the address.
        exit();
    } else {
        // Login failed
  //      header('Location: ../login.php?error=1');
        exit();
    }
} else {
    // The correct POST variables were not sent to this page.
    header('Location: ../error.php?err=Could not process login');
    exit();
}

 

Link to comment
Share on other sites

Seems I have to take out the post method for the form or it still refreshes the page.

Which means that I have to figure out how to send the login information to the server. I think I do it by adding the details at the end of the address in xlmhttp.open, although how I get these details in the first place doesn't look straightforward.

Edited by Arbu
Link to comment
Share on other sites

Removing action would mean it would submit to itself, if you didn't have event.preventDefault();

ALL actions that submit the form are taken care of through onsubmit event, by using click event on submit type button you are bypassing event onsubmit that will prevent submission, and submitting through that button click.

The hashandlogin() function should be called after event.preventDefault();

xmlhttp.open("GET", "process_login.php", true);

Will send as GET, if you use GET you have to gather the values from form inputs and send as querystring at end of "process_login.php.&email="+emailInputvalue+"&p="+passwordinputvalue;

IF you use POST you need to add input value in xhttp.send() as  xhttp.send("email="+emailInputvalue+"&p="+passwordinputvalue);

 

Link to comment
Share on other sites

Should it be the "submit" event or the "onsubmit" event. In any case I can't ever get the event.preventDefault() to trigger. If I set a break point there it doesn't get caught. If I take out the onclick property then still it doesn't trigger. 

I'll keep working on how to access the email and password from the form.

Link to comment
Share on other sites

OK here's my code now. I believe there should be a question mark after process_login.php not a full stop as you have it. Anyway I'm getting told that the post data is not set correctly.

  <?php if (login_check($mysqli) == false) :  ?>
         <div id="loginform" data-iziModal-group="grupo1">
             <button data-iziModal-close class="icon-close">x</button>  <!--watch out here - JSFormat formatted the izimodal spec to have spaces in it and the button no longer worked.-->
             <header>
             <a href="" id="signin">Sign in</a>
             </header>
             <section>
             <form name="login_form" id="login_form">
             <input type="text" placeholder="Email" name="email" class="login_email" id="login_email">
             <input id="password" type="password" placeholder="Password" name="password" class="login_password">
             <footer>
             <button data-iziModal-close>Cancel</button>
             <button class="submit" data-iziModal-close onclick="hashandlogin(this.form, this.form.password);">Log in</button>
             <p style="text-align: center; color: #444; font-size: 16px; font-family: Lato; padding-top: 70px; font-weight: 500;">
            Don't have an account? <a style="font-size: 16px; font-weight: 500; font-family: Lato;" href="register.php">Register here.</a></p>
                            </footer>
                            </form>
                        	</section>
                        </div>
				
			  <script type="text/javascript">
			  
			  document.getElementById("login_form").addEventListener("submit", function (event) {
			      event.preventDefault()
			  });
			  
		function hashandlogin(a, b) {
		    formhash(a, b);
		    var xmlhttp = new XMLHttpRequest();
		    xmlhttp.onreadystatechange = function () {
		        if (this.readyState == 4 && this.status == 200) {
		            console.log(this.responseText);
		        }
		    };
		    xmlhttp.open("GET", "includes/process_login.php?email=" +document.getElementById("login_email").value + "&p="+document.getElementById("hashedp").value, true);
		    xmlhttp.send();
		}
function formhash(a, b) {
    var c = document.createElement("input");
    a.appendChild(c), c.name = "p", c.type = "hidden", c.id="hashedp", c.value = hex_sha512(b.value), b.value = "", a.submit()
}

 

Link to comment
Share on other sites

ALL input and button using type="submit" clicking will trigger submit event on form element, even while in input and hitting enter will cause a submission of form. So ALL! YES! I MEAN ALL! inputs data etc you wish to gather and calling of functions MUST! BE INITIATED after event.preventDefault() within the curly braces where that preventDefault() is placed. Where you then gather ALL the data you wish to send to php file using AJAX.

Link to comment
Share on other sites

1 hour ago, dsonesuk said:

ALL input and button using type="submit" clicking will trigger submit event on form element, even while in input and hitting enter will cause a submission of form. So ALL! YES! I MEAN ALL! inputs data etc you wish to gather and calling of functions MUST! BE INITIATED after event.preventDefault() within the curly braces where that preventDefault() is placed. Where you then gather ALL the data you wish to send to php file using AJAX.

Yes, but as I say, regardless of whether I have type=submit or not, the event.preventDefault never gets triggered.  If I can fix that I'll have a go at putting my AJAX code in the curly braces with that. But otherwise there's no point in trying that.

Link to comment
Share on other sites

I thought the whole point we have been talking about, WAS NOT TO SUBMIT FORM CAUSING A RELOAD! and yet!

a.appendChild(c), c.name = "p", c.type = "hidden", c.id="hashedp", c.value = hex_sha512(b.value), b.value = "", a.submit(); 

the onclick event is run first and so get submitted, it might get to preventDefault() but by that time its to late! 

SO AGAIN!

Quote

ALL input and button using type="submit" clicking will trigger submit event on form element, even while in input and hitting enter will cause a submission of form. So ALL! YES! I MEAN ALL! inputs data etc you wish to gather and calling of functions MUST! BE INITIATED after event.preventDefault() within the curly braces where that preventDefault() is placed. Where you then gather ALL the data you wish to send to php file using AJAX.

LAST TIME!

Link to comment
Share on other sites

OK, good point, I hadn't noticed that that was there. So I've taken it out and now the page doesn't refresh. Hooray!

The next thing is to get the data that I send to the server to be recognised. Naturally this doesn't work first time. I don't think that the server is actually finding the data that I send. Here's my code using the post method:

function hashandlogin(a, b) {
		     formhash(a, b);
		    var xmlhttp = new XMLHttpRequest();
		    xmlhttp.onreadystatechange = function () {
		        if (this.readyState == 4 && this.status == 200) {
		            console.log(this.responseText);
		        }
		    };
			
		    xmlhttp.open("POST", "includes/process_login.php", true);
		    xmlhttp.send("email=" +document.getElementById("login_email").value + "&p="+document.getElementById("hashedp").value); 
			
		}

and

<?php

include_once 'db_connect.php';
include_once 'functions.php';

sec_session_start(); // Our custom secure way of starting a PHP session.

echo($_POST['email'] + 'abc');
exit();

The responseText is 0. What am I doing wrong?

Edit: OK, so string concatenation in php is just done with a ".".  But I'm still not getting the email setting through, just the abc. Same if I use GET and put the data after the url.

 

Edited by Arbu
Link to comment
Share on other sites

Use variable to assign input values to, its probably not working because you are using double quotes with id name, use variables and you wont have to worry about that! plus its cleaner.

check what the values are before you send, once you know that is working you can move on to next stage.

Add xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

before send();

Edited by dsonesuk
Link to comment
Share on other sites

OK, thanks very much, it seems to work OK now. I've gone with using POST rather than GET because I wasn't sure if I'd need to change INPUT_POST if I used GET. Hopefully sorting out the display at the browser end should be reasonably straightforward now.

		function hashandlogin(a, b) {
		     formhash(a, b);
		    var xmlhttp = new XMLHttpRequest();
		    xmlhttp.onreadystatechange = function () {
		        if (this.readyState == 4 && this.status == 200) {
		            console.log(this.responseText);
		        }
		    };
			var sendstring="email=" +document.getElementById("login_email").value + "&p="+document.getElementById("hashedp").value;

		    xmlhttp.open("POST", "includes/process_login.php", true);
		    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			xmlhttp.send(sendstring); 
		}

 

Link to comment
Share on other sites

At the moment I have the following. But I need to update the page to show whether the user is logged in (a) on loading and (b) when he logs in. So I'm thinking that I need to make an AJAX request in $(document).ready to see if he is logged in, then have a js function to set the details on the page that I can call from there and also when he logs in and out. I don't know if there's some way to have php simply send the log in details when the page is loaded.

<?php if (login_check($mysqli) == true) : ?> 
        						<p>Welcome <?php echo ucwords(htmlentities($_SESSION['username'])); ?>!</p>
                    </div>
                    <a href="account.php"><div class="userLogin tooltip" title="Your account">  
          						<img src="images/icons/user.png" alt="" class="iconUser">
          					</div></a>
                    <a href="includes/process_logout.php">
          						<div style="margin-right: 15px;" class="userLogin tooltip" title="Logout">
          							<img src="images/icons/logout.png" alt="" class="iconUser">
          						</div>
          					</a>
                  <?php else : ?>
        						<p>You are not signed in.</p>
                    </div>
                    <div class="userLogin tooltip" title="Login or Sign Up" data-izimodal-open="loginform" data-izimodal-transitionin="fadeInDown">
          						<img src="images/icons/user.png" alt="" class="iconUser">
          					</div>
        		<?php endif; ?>

 

Link to comment
Share on other sites

OK, setting my display items for the login status wasn't too hard. I don't need an AJAX request to find out; I can just set a variable with php on loading the page. 

The problem I'm running into now is that, if the user enters the wrong login details I'd like the login form to remain in place so that I can give him a notification to that effect and he can try to enter in again. But by the time the code gets to hashandlogin, the login form has already gone. I tried removing data-iziModal-close from the submit button and closing the loginform manually if the login details were correct, but that really messed things up. 

Any ideas? Maybe I should simply redisplay the login form with the relevant message instead of trying to get it to stay in place.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...