Check and/or set button state mvc php - php

I am new to php/mvc and experimenting with a small website.
I would like to change to state of a button depending on a select query. It's a simple 'favourite' toggle button. The query will look to the 'favourite' table of my db for the 'isFav' field (0 or 1).
I would like the button colour to be green (btn-success) if the query finds a result (1), and the colour to be default (btn-default) if not (0).
Should be simply but I can't seem to get it. I think I am getting confused regarding passing of the variables between my view and model.
My books_model.php code is as follows
class BooksModel
{
public function isFav()
{
$book_id = $_GET['id']; // from url
$user_id=$_SESSION['user_id'];
$sql = "SELECT isFav FROM favourite WHERE book_id = :book_id AND user_id = :user_id AND isFav = 1";
$query = $this->db->prepare($sql);
$query->bindParam(':book_id', $book_id);
$query->bindParam(':user_id', $user_id);
$query->execute();
if ($query->rowCount() == 1) {
$css = 'btn-success';
echo $css; //for testing
} else {
$css = 'btn-default';
echo $css; // for testing
}
}
}
My books.php controller is as follows;
class Books extends Controller
{
function itemView()
{
$itemView_model = $this->loadModel('Books');
$this->view->books = $itemView_model->itemView();
$this->view->render('books/itemView');
$itemView_model->isFav();
}
}
My itemView.php html button code is as follows;
echo '<button class="btn '.$css.'"></button>';
The only thing printed on the page is a btn-success or btn-default (top left). This toggles whenever I click the button. Therefore I assume my query is working.
Apologies for the code I am a newbie and I do appreciate any help offered, even a point in the right direction.

Try this:
public function isFav() {
(...)
if ($query->rowCount() == 1) {
$css = 'btn-success';
echo $css; //for testing
} else {
$css = 'btn-default';
echo $css; // for testing
}
return $css;
}
And in your View:
echo "<button class=\"btn ".$itemView_model->isFav()."\"></button>";
The reason: Your Variable $css in your isFav() method is not known in your view (the scope of the variable is the isFav() method).
This line:
$itemView_model->isFav();
Requests the return value of this function, so, clearly, the value bust be returned in order to be available.
The reason you see the seemingly correct answer printed is that the echo call is in the same scope as the $css variable.

Related

Puzzle with PHP using codeigniter

I have a problem using codeigniter, now I have a system that show you a question in a page called start, the question comes random from the database using this code.
$data['question'] = $this->Setting->Loop('challenges_questions', 'ORDER BY RAND() LIMIT 1');
then check the form_validation
if($this->form_validation->run() === TRUE){
foreach($data['question']->result() as $ques){
$query = $this->Challenges_Model->addAnswer($ques->the_answer);
}
}
this is the model
public function addAnswer($answer){
if($this->input->post('answer') == $answer){
if(!$this->session->userdata('is_stopped')){
$this->db->query("UPDATE challenges_scores SET points = points+1 WHERE user_id = ".$this->session->userdata('id').";");
//$this->db->set('points' , 'points+1');
//$this->db->where('user_id', $this->session->userdata('id'));
//$this->db->update('challenges_scores');
}else{
// unSet
$this->session->unset_userdata('is_stopped');
}
return TRUE;
}else{
return FALSE;
}
}
now my problem is when the user post the input (the answer), the query is refreshed, then the answer is changed then the form input answer is wrong.
is there any way to save data to use it after the post ?
The logic is the same as an update form:
Model:
function get() {
return $this->db->get('sometable')->result();
}
Controller:
function index() {
$data['result'] = $this->sommodel->get();
$this->load->view('someview', $data);
}
Here we get the post value if there is any (in case of bad form validation submit) and if not we have the value from the db
<input name="somefield" value="<?php isset($_POST['somefield']) { echo $_POST['somefield'] } else { echo $result->somefield; } ?>">
If it's just one thing just store it in a session variable and do the same logic by instead of $result->somefield you put $this->session->somefield. I wouldn't recommend this approach if it's alot of data.

the data do not display in my view

Undefined variable: data in my view
This is a simple display data in the input.
So, why this input isn't display my query result at it?
my view
<input type="text" name="sitename" value="<?php echo $data['sitename']; ?>"><br>
model
public function getData()
{
$query = "SELECT * FROM $this->tablename ORDER BY 'id' DESC LIMIT 1";
if (!$sqli = mysqli_query($this->cxn->connect(),$query))
{
throw new Exception("Error Processing Request");
}
else
{
$num = mysqli_num_rows($sqli);
while ($num > 0)
{
$data = mysqli_fetch_array($sqli);
$num--;
}
return $data;
}
}
Simply because a variable is declared somewhere, doesn't mean it is available everywhere. All variables have scope in which they are accessible. See this: http://php.net/manual/en/language.variables.scope.php for more information on scope.
You need to pass the $data variable into your view. I image you're using some sort of MVC framework since you have a model and a view. If this is the case you can lookup how to pass variables into views in that specific framework. The basic structure of your controller method might look something like this:
//sudo code - not specific to an actual framework
public function controller_method()
{
$data = $model->getData();
$this->template->set('data',$data);
$this->template->load('view');
}
Just search how to do that in your specific framework. Hope that helps!
EDIT
Base on your comment it looks like you're setting data after you load the view. You need to swap the order and call $display = new Display("main"); $data = $display->getData(); before you include'../model/display.php';
If the query returns 0 rows, your while() loop will never execute, so it won't set $data.
Since you're only returning 1 row from the query, you don't need a loop, you can just use an if. Then you can return $data only when it succeeds.
public function getData()
{
$query = "SELECT * FROM $this->tablename ORDER BY 'id' DESC LIMIT 1";
if (!$sqli = mysqli_query($this->cxn->connect(),$query))
{
throw new Exception("Error Processing Request");
}
else
{
if ($data = mysqli_fetch_array($sqli))
{
return $data;
}
else
{
return null;
}
}
}

Call a function from a "html table" in drupal 7

I need to call the FUNCTION when the BUTTON is clicked. How I can do this?
(I know that the code I wrote is wrong, it's just to make it clear)
function gh_view_categories(){
$a='<table>';
$a.='<tr>';
$a.='<td><strong>'.'Categoria:'.'</strong></td>';
$a.='<td><strong>'.'Soglia minima:'.'</strong></td>';
$a.='<td><strong>'.'Tot attuale:'.'</strong></td>';
$a.='<td><strong>'.'Crea ordine'.'</strong></td>';
$a.='</tr>';
$query = db_select('uc_product_classes', 'u')
->fields('u', array('name','soglia', 'totattuale'));
$result = $query->execute();
while ($record = $result->fetchAssoc()) {
$idUser=gh_get_user_id($record['name']);
$a.='<tr>';
$a.='<td>'.$record['name'].'</td>';
$a.='<td>'.$record['soglia'].'</td>';
$a.='<td>'.$record['totattuale'].'</td>';
$a.='<td>'.l('BUTTON', FUNCTION($idUser)')).'</td>';
$a.='</tr>';
}
$a.='</table>';
return $a;
}
You need to add this in your html button tag:
<button onClick="yourFunction()">

How to call class method as form action php mvc application if it's even possible?

I'm trying to write a simple mvc application with php and mysql. I'm very new to mvc and relativly new to php aswell. I'm letting the user choose from different movies and then add the ones they want to their own list. But I can't figure out how to get the correct form action to insert the choosen movie into the db.
This is how my two model class methods looks like:
public function checkMovie() {
// Check if movie exist in db.
$stmt = $this->dbh->prepare("SELECT * FROM watchlist WHERE my_title='{$_POST['my_title']}'");
$stmt->bindParam(':my_title', $_POST['my_title']);
$stmt->execute();
$rows = $stmt->fetchALL();
$this->n = count($rows);
}
public function addMovie() {
// Add choosen movie to db.
$sql = $this->dbh->prepare("INSERT INTO watchlist(my_title, my_des, my_link)
VALUES ('{$_POST['my_title']}', '{$_POST['my_des']}', '{$_POST['my_link']}')");
$sql->bindParam(':my_title', $_POST['my_title'], PDO::PARAM_STR);
$sql->bindParam(':my_des', $_POST['my_des'], PDO::PARAM_STR);
$sql->bindParam(':my_link', $_POST['my_link'], PDO::PARAM_STR);
$sql->execute(array(':my_title' => $_POST['my_title'],':my_des' => $_POST['my_des'],':my_link' => $_POST['my_link']));
}
As you can see I have the basic sql-code in here and then I call the methods from a method in my controller:
public function getAddMovie() {
$this->addModel = new AddMovieModel();
if (isset($_POST['submit'])) {
// Call checkmovie from addmoviemodel and check if movie allready is taken.
$checkmovie = $this->addModel->checkMovie();
if($this->n > 0) { // Should this logic perhaps be in my model?
// Shows javascript-popup eg. 'movie allready added'.
include 'view/viewscripterror.php';
}
else { // Call addMovie from addmoviemodel to insert movie to db.
$addmovie = $this->addModel->addMovie();
// Shows javascript-popup eg. 'movie is now added'.
include 'view/viewscriptsuccess.php';
}
}
}
I'm not sure if the if($this->n > 0) perhaps should be in my model aswell?
And here's the form, I can't figure out what to pass as form action? This problem has been driving me crazy for a while now and that's why I'm turning here in hope for some help.
echo '<form action="??" method="post">',
'<input type="hidden" name="my_title" value="'.$title.'">',
'<input type="hidden" name="my_des" value="'.$description.'">',
'<input type="hidden" name="my_link" value="'.$link.'">',
'<input type="submit" name="submit" value="Peppa!">',
'</form></div>';
Try like
echo '<form action="http://site_url/getAddMovie" method="post">',
You need to pass the url of the function getAddMovie into the action,then after submitting it,it will post/get the params into that function.
And try to load the model like
$this->load->model('AddMovieModel');
And try to call it like
$checkmovie = $this->AddMovieModel->checkMovie();
Or even you can try like
$addModel = new AddMovieModel();
and call it like
$checkmovie = $addModel->checkMovie();

Using flashdata while posting same controller twice in Codeigniter

I am trying to submit a EDIT form which edits Users Academics Details,
These Details have unique id in DB and my Code in Short Looks like below :
class edit extends ci_controller
{
function user_academics($id = NULL)
{
if(isset($id) == FALSE) //if link is ./edit/user_academics
{
$id = NULL;
$link = site_url('profile');
show_error("Invalid Page Request! <a href='$link' Go to Profile </a>");
}
$user_id = $this->session->userdata('user_id');
$data['fill'] = $this->edit_model->get_user_academics($id);
if($user_id != $data['fill']['user_id']) // check if logged in user is accessing his record or others
{
$link = site_url('profile');
show_error("This is an Invalid Request ! <a href='$link'>Go to Profile </a>");
}
else // actual work starts here
{
$this->session->set_flashdata('ua_id',$id); // update_academics will get this data
$this->load->view('edit/edit_3_view',$data);
}
}
function update_academics()
{
$ua_id = $this->session->flashdata('ua_id'); // flash data used here .
if( !$ua_id )
{
show_error('Sorry, This request is not valid!');
}
$academics = array(
// All post values
);
$this->edit_model->update_user_academics($academics,$ua_id);
//print_r($academics);
redirect('profile');
}
}
Now the problem is
- If I open two different records to edit, then It will set only one Session Flash value.
- And No matter what I edit , the existing values of the last flash value gets updated.
Please Suggest me another way or Correct me if I am wrong in above code . Thanks
save that flashdata in array, like:
$myArr = array('value 1', 'value 1');
//set it
$this->session->set_flashdata('some_name', $myArr);
And in view:
$dataArrs = $this->session->flashdata('some_name');
//loop thru $dataArrs to show the flashdata
Flash data is simply like variable which is available only in next request, you can bypass this behavior by using two different keys with record id in it, so that when you use flash data for showing message you can access key with particular record id.

Categories