CodeIgniter update page - Simple CRUD website assistance required - codeigniter

After looking through the forums and starting to try to create a basic CRUD website I am currently struggling to have a page that updates the articles as follows. If someone could kindly tell me where I am going wrong, I will be most greatful. I am getting a 404 error at 'news/input'
model (at news_model.php)
public function update($id, $data)
{
$this->db->where('id', $id);
$this->db->update('news', $data);
}
controller (news.php)
public function update($id){
$data = array(
'title' => $this->input->post('title'),
'slug' => $this->input->post('slug'),
'text' => $this->input->post('text'));
if($this->news_model->exists($id)) {
$this->news_model->update($id, $data);
}
else {
$this->news_model->insert($data);
}
}
html (views/news/input.php)
<h2>Update a news item</h2>
<?php echo validation_errors(); ?>
<?php echo form_open('news/update') ?>
<label for="title">Title</label>
<input type="input" name="title" /><br />
<label for="slug">Slug</label>
<input type="input" name="slug" /><br />
<label for="text">Text</label>
<textarea name="text"></textarea><br />
<input type="submit" name="submit" value="Update an item" />

You get a 404 because your news controller seems to have no method 'input'. Try adding something like this:
public function input(){
// load the form
$this->load->view('/news/input');
}
Note that for updating data you will need to fetch and pass it into the view first, then render the (filled out) form using set_val() and other CI functions.
Currently you're "hardcoding" the HTML form which makes populating and maintaining state (when validation fails) difficult. I suggest you play through the forms tutorial on the CI website.
Edit:
To create a update/insert (upsert) controller change as follows:
Controller:
function upsert($id = false){
$data['id'] = $id; // create a data array so that you can pass the ID into the view.
// you need to differntiate the bevaviour depending on 1st load (insert) or re-load (update):
if(isset($_POST('title'))){ // or any other means by which you can determine if data's been posted. I generally look for the value of my submit buttons
if($id){
$this->news_model->update($id, $this->input->post()); // there's post data AND an id -> it's an update
} else {
$this->news_model->insert($id, $this->input->post()); // there's post data but NO id -> it's an insert
}
} else { // nothing's been posted -> it's an initial load. If the id is set, it's an update, so we need data to populate the form, if not it's an insert and we can pass an empty array (or an array of default values)
if($id){
$data['news'] = $this->news_model->getOne($id); // this should return an array of the news item. You need to iterate through this array in the view and create the appropriate, populated HTML input fields.
} else {
$data['news'] = $this->news_model->getDefaults(); // ( or just array();) no id -> it's an insert
}
}
$this->load->view('/news/input',$data);
}
And amend the $id to the action-url in your view:
<?php echo form_open('news/upsert/'.$id) ?>

Related

Laravel 6: 2 buttons in one form performing different functions

I have a form with 2 buttons, 1 button saves the changes to the form to a db(including the filename in the field named "attachment", the second button uploads the actual file to the server.
I was able to have each button echo save or upload depending on the press, so the form reads which button is pressed and the save function also works. However the the upload function doesn't seem to read the input field named "attachment"
I am using 1 controller with three functions. The html code for the buttons is:
<input type="file" name="attachment" enctype="multipart/form-data"/>
<p align="center">
<input type="submit" btn btn-primary class="btn btn-primary" id="upload" name="action" value="upload">
<input type="submit" btn btn-primary class="btn btn-primary" id="save" name="action" value="save">
The controller has 3 functions, one overall function which calls either the update or upload function, one that saves the changes, one that is supposed to upload the file
Overall:
public function store(Request $request, $_id = false, $attachment = false){
//check which submit was clicked on
if($request->action == 'upload'){
//
$this->upload($request);
return redirect()->route('home');
} elseif($request->action == 'save') {
//echo 'save pressed';
//run function save all form fields
$this->update($request, $_id);
return redirect()->route('home');
} else {echo "error";}
}
Save changes: (the one that works)
public function update (Request $request, $_id){
//$this->upload($request);
/*
$path = $request->file('attachment');
$path->storeas('/public','123'); */
$data = post::findOrFail($_id);
$data->title = $request->title;
$data->content = $request->content;
$data->shorttext = $request->shorttext;
$data->created_by = $request->created_by;
$data->text3 = $request->text3;
$data->attachment = $request->attachment;
$data->save();
/* return response()->json([
'name' => 'Abigail',
'state' => 'CA'
]); */
if($data){
return redirect()->route('home');
}else{
return back();
}
}
Upload:
function upload(Request $request){
$path = $request->file('attachment');
// $original = $request->file('attachment')->getClientOriginalName();
$path->store('/public');
//return $original;
}
Upload gives an error: Call to a member function store() on null
I think this means it cannot read the field "attachment" therefore it returns null and cant upload anything. Maybe this has something to do with the fact the from uses #put and the upload needs post?
I have tested the upload function itself in a separate blade and a separate controller and there it works but as i said the method is post in that case.
For completeness the routes to my form and my separate upload test bewlo (any help is much appreciated (I would love to have both functions on 1 button, so i coud press the button and it uploads a file, saves the changes and stores the filename in the DB , but I will settle for 2 buttons for now.
Route::put('/post/update/{_id}', 'PostController#store')->name('post.update');
//test for upload only
Route::post('/upload', "UploadController#upload")->name('upload');

How to redirect back to preivous template with both input and collections of Eloquent in Laravel?

I need to pass both input and collections, that this controller produce, to the previous template. I try to use:
return redirect()->back->withInput()->with('userdata',$userdata);
but get undefined variable when access $userdata in template. This is controller:
public function inquireUpdateProcess(){
$input = request()->all();
$userdata = AuthorityKind::where('authority', $input['authority'])->first();
return redirect()->back->withInput()->with('userdata',$userdata);
}
And this is template of view:
<label for="text-authority-change">name of authority:</label>
<input type="text" name="authority_name_change" class="form-control"
value="{{$userdata->authority_name}}" />
I use the following instead then it works. But the outcome is couldn't pass the input data and collection in the same time, I know there must be a way to use return redirect()->back()... and get both previous input and the collection in template.
$userdata = AuthorityKind::where('authority', $input['authority'])->first();
$binding = [
'title' => 'Authority management',
'userdata' => $userdata,
];
return view('authority.authView', $binding);
I found out the data put into with() can only get it by session in template of blade like this :
<input type="text" id="text-authority-change" name="authority_name_change" class="form-control"
value="{{session()->get('userdata')['authority_name']}}"
/>
Even the collections of Eloquent are the the same way to access.

Get specific row from database with codeigniter

I'm new to this so i have this silly question.I want to make a login form and when the user logs in i want to show all his information in the screen(username attack defence...).The thing is i don't know how to call the specific function i've made because in my controller calls function index() by default and not the function guser().
login view
<h2>Login</h2>
<?php if($error==1){ ?>
<p>Your Username/password did not match </p>
<?php } ?>
<form action="<?=base_url()?>index.php/Users/login" method="post">
<p>Username: <input name="user" type="text" /> </p>
<p>Password: <input name="password" type="password" /> </p>
<p><input type="submit" value="Login" /></p>
</form>
users controller
<?php
class Users Extends CI_Controller{
function __construct(){
parent::__construct();
$this->load->model('User');
}
function index(){
$data['users']=$this->User->get_users();//sto model post tha kalesei tin sinartisi get_posts
$this->load->view('Post_index',$data);
}
function guser($id){
$data['user']=$this->User->get_user($id);
$this->load->view('Post_index',$data);
}
function login(){
$data['error'] = 0; // simenei oti den exei errors
if($_POST){
$user=$this->input->post('user',true);//pairnei to username p edose o xristis(einai idio me to $_POST)
$password=$this->input->post('password',true);//pairnei to password p edose o xristis
//$type=$this->input->post('charact',true);
$user1=$this->User->login($user,$password);//,$type);
if(!$user1){
$data['error']=1;
}else{
$this->session->set_userdata('id',$user1['id']);
$this->session->set_userdata('user',$user1['user']);
$this->session->set_userdata('name',$user1['name']);
$this->session->set_userdata('money',$user1['money']);
$this->session->set_userdata('attack',$user1['attack']);
$this->session->set_userdata('defence',$user1['defence']);
$this->session->set_userdata('level',$user1['level']);
$this->session->set_userdata('xp',$user1['xp']);
redirect(base_url().'index.php/Users');
}
}
$this->load->view('Login',$data);
}
function registerSam(){
if($_POST){
$data=array(
'user'=>$_POST['user'],
'name'=>$_POST['name'],
'password'=>$_POST['password'],
'charact'=>"Samurai",
'money'=>400,
'attack'=>10,
'defence'=>5,
'level'=>0,
'xp'=>0
);
$userid=$this->User->create_user($data);
}
}
function registerKnight(){
if($_POST){
$data=array(
'user'=>$_POST['user'],
'name'=>$_POST['name'],
'password'=>$_POST['password'],
'charact'=>"Knight",
'money'=>400,
'attack'=>5,
'defence'=>10,
'level'=>0,
'xp'=>0
);
$userid=$this->User->create_user($data);
}
}
}
?>
user model
<?php
class User Extends CI_Model{
function create_user($data){
$this->db->insert('unityusers',$data);
}
function login($user,$password){
$where=array(
'user'=>$user,
'password'=>$password,
);
$this->db->select()->from('unityusers')->where($where);
$query=$this->db->get();
return $query->first_row('array');
}
function get_user($id){
$this->db->select()->from('unityusers')->where(array('id'=>$id));
$query=$this->db->get();
return $query->first_row('array');
}
function get_users($num=20,$start=0){// tha paroume 20 posts k tha arxisoume apo to proto
$this->db->select()->from('unityusers')->limit($num,$start);
$query=$this->db->get();
return $query->result_array();
}
}
?>
Although you have accepted the answer I like to point out some basic functionality for you to more improved code.
Different technique to load the data to view from controller:
function index(){
$users = $this->User->get_users();
$this->load->view('Post_index',['users' => $users, 'any_other_data' => $any_other_data ... and so on]);
}
When you get post data in the controller then you should check for a validation first inside your login function. And in login functionality it will be more useful. setting-validation-rules
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required',
Loading a model and it's function. You don't need to use uppercase in this as give below.
$this->load->model('user');
$this->user->get_users();
Your registration Function registerSam you don't need to create an array of post data Codeigniter will provide the functionality to get all your post data at once. To remove unnecessary data from that array use unset.
$your_post_array = $this->input->post();
To call a specific function made, you can access it via a browser using the link
BASE_URL/index.php/ControllerName/MethodName
So, in your case to call the guser method, the url would be
BASE_URL/index.php/users/guser
Hope that helps.
You have an error in guser function on the controller. You don't need to passs any argument to the function. You can get ID of user from the session, which was actually added in session once the user has entered correct credentials.
Also after login, you need to redirect user to guser function instead of users. Because as per your controller users function dosen't exist.
Change From
redirect(base_url().'index.php/Users');
To
redirect(base_url().'index.php/guser');
Please check below for solution.
function guser(){
$data['user']=$this->User->get_user($this->session->userdata('id'));
$this->load->view('Post_index',$data);
}
Let me know if it not works.

How do I insert one to many relational multi data to same table in Laravel?

My table structure is:
id | parent_id | name.
My Menu model one to many relationship is:
public function childMenus() {
return $this->hasMany( ‘App\Menu’, ’parent_id’);
}
public function parentMenus() {
return $this->belongsTo(‘App\Menu’, ‘parent_id’);
}
I am creating menus with sub menus.For example I have to set 'Parent Menu' with three child menus.For this I have created a form with four inputs field.
<form>
<input type="text" name="parent">
<input type="text" name="child[]">
<input type="text" name="child[]">
<input type="text" name="child[]">
</form>
Now I want to save parent menu with its child menus at the same time.I tried to save them in array but its not working in Laravel.
Please also explain what would be the controller method for saving this data.
Thanks in advance
You can use the saveMany method to attach multiple children to a parent.
// Assuming whatever goes into the text box goes in the "name" field.
$parent = new \App\Parent();
$parent->name = \Input::get('name');
$parent->save();
$children = [];
foreach (Input::get('child') as $child) {
$children = new \App\Child([
'name' => $child
]);
}
$parent->childMenus()->saveMany($children);
I found the solution for my question.Here I am posting...
$parent_menu = $request->input('parent');
$parent = Menu::create(['name' => $parent_menu]);
$parent->save();
$child_menus = $request->input('child');
foreach($child_menus as $child_menu) {
$child = $parent->pages()->create(['name' => $child_menu]);
$child->save();
}

Yii ClinkPager doesn't work on Ajax Request

Firstly, when the page gets loaded, ClinkPager works properly with all the paging correctly displayed.
But when Ajax Request is sent, the results get populated correctly with all the paging.
But clicking on the next or another page in the Paging, the previous data gets loaded and also paging shows different sequence.
/*Controller action to fetch the records and apply the pagination*/
//---------------------------------------------------------------
public function actionGetUser($user_id=null)
{
$user_domain= (isset($_POST['user_domain'])?$_POST['user_domain']: null);
$model=new UserSearch();
$criteria=new CDbCriteria();
//If Category/Title are also specified for search, then its an Ajax request.
if((isset($_POST['ajax_search'])) && ($_POST['ajax_search']==1))
{
//Change the search criteria accordingly
$criteria->select="*";
if($user_domain!= null)
{
//Adding criteria to search for ideas of specific domain
$criteria->addCondition("user_domain=".$usr_domain);
}
}
//Retrieve the users.
$searchData = $model->search();
//Count the no. of results retrieved.
$count=UserSearch::model()->count($criteria);
//Enable pagination
$pages=new CPagination($count);
$searchData->setPagination($pages);
$pages->applyLimit($criteria);
//Search for ideas satisfying that criteria
$models=userSearch::model()->findAll($criteria);
if((isset($_POST['ajax_search'])) && ($_POST['ajax_search']==1))
{
//Rendering the respective page
$this->renderPartial('renderOnAjax', array(
'user' => $models,
'pages' => $pages,
'user_count'=>$count
));
}
else
{
//Rendering the respective page
$this->render('render', array(
'user' => $models,
'pages' => $pages,
'user_count'=>$count
));
}
}
//------------------------------------------------------------
/*render page*/
//------------------------------------------------------------
<div>
<div class="userInfo" id="user_search_result">
<?php $this->renderPartial("renderOnAjax",array('user'=>$user, 'pages'=>$pages));?>
</div>
</div>
//------------------------------------------------------------
/*renderOnAjax Page*/
//------------------------------------------------------------
<?php
$i=0;
$count=count($user);?>
<?php while($i!=$count) {?>
<?php $row=$count[$i];?>
<div class="Box">
/*Some contain to display...*/
</div>
<?php $i++;?>
<?php } ?>
<div class="row">
<?php $this->widget('CLinkPager', array(
'pages' => $pages
));
?>
</div>
//---------------------------------------------------------
try
<?php $this->renderPartial("renderOnAjax",array('user'=>$user, 'pages'=>$pages),false,true);?>
Here is official documentioan for renderPartial
public string renderPartial(string $view, array $data=NULL, boolean $return=false, boolean $processOutput=false)
$view=string name of the view to be rendered. See getViewFile for details about how the view script is resolved.
$data=array data to be extracted into PHP variables and made available to the view script
$return=boolean whether the rendering result should be returned instead of being displayed to end users
$processOutput=boolean whether the rendering result should be postprocessed using processOutput.
{return} string the rendering result. Null if the rendering result is not required.
EDIT:
The above scheme works for ajax call renderPArtials. You should try this where you are rendering ajax request in controller action like
$this->renderPartial('renderOnAjax', array(
'user' => $models,
'pages' => $pages,
'user_count'=>$count
),false,true);

Resources