Hello, encontro-me a desenvolver um CRUD para editar notícias num website pessoal. Implementei usando AngularJS, PHP, MySql e o Materialize para o design. No meu formulário para criar/editar, tenho um campo (<textarea>) onde o utilizador deve introduzir o texto da notícia.
Tudo funciona bem até introduzir nesse campo um parágrafo. Se o fizer, assim que clico "update" nada acontece. Se fizer "refresh" à página, os dados não são mais apresentados na tabela. Tenho de aceder à base de dados no servidor, remover o parágrafo para voltarem a ser apresentados os dados na tabela.
Alguma ideia no que possa causar este bug?
index.html:
<!-- table that shows product record list -->
<table class="hoverable bordered">
<thead>
<tr>
<th class="text-align-center">ID</th>
<th class="width-10-pct">Heading</th>
<th class="width-10-pct">Subheading</th>
<th class="width-10-pct text-align-center">Text</th>
<th class="text-align-center action-text">Action</th>
</tr>
</thead>
<tbody ng-init="getAll()">
<tr dir-paginate="d in news | filter:search | itemsPerPage:5" pagination-id="prodx">
<td class="text-align-center">{{ d.id_news }}</td>
<td>{{ d.news_heading }}</td>
<td>{{ d.news_subheading }}</td>
<td>{{ d.news_text }}</td>
<td>
<a ng-click="readOne(d.id_news)" class="waves-effect waves-light btn"><i class="material-icons left">edit</i></a>
<a ng-click="deleteArticle(d.id_news)" class="waves-effect waves-light btn"><i class="material-icons left">delete</i></a>
</td>
</tr>
</tbody>
</table>
<!-- angular pagination -->
<dir-pagination-controls pagination-id="prodx" boundary-links="true" on-page-change="pageChangeHandler(newPageNumber)" template-url="app/shared/dir_pagination.tpl.html"></dir-pagination-controls>
<!-- modal for for creating new arctile -->
<div id="modal-product-form" class="modal">
<div class="modal-content">
<h4 id="modal-product-title">Create New Article</h4>
<div class="row">
<div class="input-field col s12">
<input ng-model="news_heading" type="text" class="validate" id="form-news_heading" placeholder="Type article heading here..." />
<label for="news_heading">Heading</label>
</div>
<div class="input-field col s12">
<input ng-model="news_subheading" type="text" class="validate" placeholder="Type article subheading here..."/>
<label for="news_subheading">Subheading</label>
</div>
<div class="input-field col s12">
<textarea ng-model="news_text" type="text" class="validate materialize-textarea" id="form-news_text" placeholder="Type article text here..." ></textarea>
<label for="news_text">Text</label>
</div>
<div class="input-field col s12">
<a id="btn-create-product" class="waves-effect waves-light btn margin-bottom-1em" ng-click="createArticle()"><i class="material-icons left">add</i>Create</a>
<a id="btn-update-product" class="waves-effect waves-light btn margin-bottom-1em" ng-click="updateArticle()"><i class="material-icons left">edit</i>Save Changes</a>
<a class="modal-action modal-close waves-effect waves-light btn margin-bottom-1em"><i class="material-icons left">close</i>Close</a>
</div>
</div>
</div>
</div>
<!-- floating button for creating product -->
<div class="fixed-action-btn" style="bottom:45px; right:24px;">
<a class="waves-effect waves-light btn modal-trigger btn-floating btn-large red" href="#modal-product-form" ng-click="showCreateForm()"><i class="large material-icons">add</i></a>
</div>
app.js:
var app = angular.module('myApp', ['angularUtils.directives.dirPagination']);
controller.js
app.controller('newsCtrl', function($scope, $http) {
.
.
.
// update product record / save changes
$scope.updateArticle = function(){
$http({
method: 'POST',
data: {
'id_news' : $scope.id_news,
'news_heading' : $scope.news_heading,
'news_subheading' : $scope.news_subheading,
'news_text' : $scope.news_text
},
url: 'api/product/update.php'
}).then(function successCallback(response) {
// tell the user product record was updated
Materialize.toast(response.data, 4000);
// close modal
$('#modal-product-form').modal('close');
// clear modal content
$scope.clearForm();
// refresh the product list
$scope.getAll();
});
}
// retrieve record to fill out the form
$scope.readOne = function(id_news){
// change modal title
$('#modal-product-title').text("Edit Article");
// show udpate product button
$('#btn-update-product').show();
// show create product button
$('#btn-create-product').hide();
// post id of product to be edited
$http({
method: 'POST',
data: { 'id_news' : id_news },
url: 'api/product/read_one.php'
}).then(function successCallback(response) {
// put the values in form
$scope.id_news = response.data[0]["id_news"];
$scope.news_heading = response.data[0]["news_heading"];
$scope.news_subheading = response.data[0]["news_subheading"];
$scope.news_text = response.data[0]["news_text"];
// show modal
$('#modal-product-form').modal('open');
})
.error(function(data, status, headers, config){
Materialize.toast('Unable to retrieve record.', 4000);
});
}
// read products
$scope.getAll = function(){
$http({
method: 'GET',
url: 'api/product/read.php'
}).then(function successCallback(response) {
$scope.news = response.data.records;
});
}
});
product.php:
<?php
class Product{
// database connection and table name
private $conn;
private $table_name = "news";
// object properties
public $id_news;
public $news_heading;
public $news_subheading;
public $news_text;
public $news_image_path;
// constructor with $db as database connection
public function __construct($db){
$this->conn = $db;
}
.
.
.
// update the product
function update(){
// update query
$query = "UPDATE
" . $this->table_name . "
SET
news_heading = :news_heading,
news_subheading = :news_subheading,
news_text = :news_text
WHERE
id_news = :id_news";
// prepare query statement
$stmt = $this->conn->prepare($query);
// sanitize
$this->news_heading=htmlspecialchars(strip_tags($this->news_heading));
$this->news_subheading=htmlspecialchars(strip_tags($this->news_subheading));
$this->news_text=htmlspecialchars(strip_tags($this->news_text));
$this->id_news=htmlspecialchars(strip_tags($this->id_news));
// bind new values
$stmt->bindParam(':news_heading', $this->news_heading);
$stmt->bindParam(':news_subheading', $this->news_subheading);
$stmt->bindParam(':news_text', $this->news_text);
$stmt->bindParam(':id_news', $this->id_news);
// execute the query
if($stmt->execute()){
return true;
}else{
return false;
}
}
// used when filling up the update product form
function readOne(){
// query to read single record
$query = "SELECT
news_heading, news_subheading, news_text
FROM
" . $this->table_name . "
WHERE
id_news = ?
LIMIT
0,1";
// prepare query statement
$stmt = $this->conn->prepare( $query );
// bind id of product to be updated
$stmt->bindParam(1, $this->id_news);
// execute query
$stmt->execute();
// get retrieved row
$row = $stmt->fetch(PDO::FETCH_ASSOC);
// set values to object properties
$this->news_heading = $row['news_heading'];
$this->news_subheading = $row['news_subheading'];
$this-> news_text = $row['news_text'];
}
update.php:
<?php
// include database and object files
include_once '../config/database.php';
include_once '../objects/product.php';
// get database connection
$database = new Database();
$db = $database->getConnection();
// prepare product object
$product = new Product($db);
// get id of product to be edited
$data = json_decode(file_get_contents("php://input"));
// set ID property of product to be edited
$product->id_news = $data->id_news;
// set product property values
$product->news_heading = $data->news_heading;
$product->news_subheading = $data->news_subheading;
$product->news_text = $data->news_text;
// update the product
if($product->update()){
echo "Product was updated.";
}
// if unable to update the product, tell the user
else{
echo "Unable to update product.";
}
?>
Thanks in advance
↧