By overriding the delete function of GroceryCRUD as below, we can easily soft-delete a record.
public function user() {
$crud = new grocery_CRUD();
$crud->set_table('cms_user');
$crud->set_subject('User List');
$crud->required_fields('user_name');
$crud->columns('user_name','email','real_name','active');
$crud->change_field_type('active', 'true_false');
$crud->callback_delete(array($this,'delete_user'));
$output = $crud->render();
$this->_example_output($output);
}
public function delete_user($primary_key) {
return $this->db->update(
'cms_user',
array('deleted' => '1'),
array('id' => $primary_key)
);
}
My question is, How do I hide the soft-deleted records in the Main View ??
Thank you.
The answer was easy... after some googling it is obvious I can use the where clause
$crud->where('deleted', '0');
Thank you all... works like a charm
Related
I'm new in Laravel 9 but for my project I need to create a pivot table with multiple foreign keys. This is what the migration looks like.
public function up()
{
Schema::create('language_user', function (Blueprint $table) {
$table->id();
$table->foreignId('language_id')->constrained()->onDelete('cascade');
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->foreignId('proficiency_id')->constrained()->default(1)->onDelete('cascade');
$table->foreignId('motivation_id')->constrained()->default(1)->onDelete('cascade');
$table->foreignId('lang_status_id')->constrained()->default(1)->onDelete('cascade');
$table->timestamps();
});
Now, i'm trying to insert the data from a Livewire component, so I tried to create a Model for the pivot table but it didn't work. Can you point me in the right direction?
I removed the default values from the migration, from some reason they weren't working. The I used this in the Livewire controller:
public function addLanguage(Language $language)
{
$user = auth()->user();
$data = $this->validate();
$language->id = $data['language'];
//create user language record
$language->users()->attach($user->id, ['proficiency_id' => 1 , 'motivation_id' => 1, 'lang_status_id' => 1]);
//message
//redirect
return redirect(route('dashboard'));
}
And this worked. I hope this can help someone else.
I removed the default values from the migration, from some reason they weren't working. The I used this in the Livewire controller:
public function addLanguage(Language $language)
{
$user = auth()->user();
$data = $this->validate();
$language->id = $data['language'];
//create user language record
$language->users()->attach($user->id, ['proficiency_id' => 1 , 'motivation_id' => 1, 'lang_status_id' => 1]);
//message
//redirect
return redirect(route('dashboard'));
}
And this worked. I hope this can help someone else.
I'd like to have a search input, that display the result on keypress.
At the moment, this is what I have :
mylist: Observable<MyData[]>;
term = new FormControl();
ngOnInit() {
this.mylist = this.term.valueChanges
.debounceTime(400)
.distinctUntilChanged()
.switchMap(term => this.searchData(term));
}
searchData(valueToSearch:string){
if(valueToSearch == ''){
this.channels = MyData.find();
}
return MyData.find({'title':new RegExp(valueToSearch)});
}
It works quite well, but I have trouble to initialize "mylist", and I think my method isn't performant at all.
Basically, I want when my component is initialize, that:
this.mylist = MyData.find();
And on keypress, I want my search to be done on this.mylist, to avoid doing too much request.
Is it possible ?
I hope I'm clear.
Thanks by advance guys.
You must subscribe to the mapped data. Modify to the below code
this.term.valueChanges
.debounceTime(400)
.distinctUntilChanged()
.switchMap(term => this.searchData(term))
.subscribe((result) => {
this.mylist = result
});;
#Julia is correct , modify your searchData() function as below
searchData(valueToSearch:string):Observable<any> {
if(valueToSearch == ''){
this.channels = MyData.find();
}
return <Observable<any>>MyData.find({'title':new RegExp(valueToSearch)});
}
I want to handle application feedback regarding, in this case, form validation.
To do this I check for model validation in controller, using
// VALIDATE
if ($this->Event->validates($this->data))
{
// SAVE
$this->Event->create();
if ($this->Event->saveAll($this->data, array('validate' => false)))
{
$this->Session->setFlash('Evenimentul a fost salvat!', 'flash_admin_success');
$this->redirect(array('action' => 'index', 'admin' => true));
} else {
$this->Session->setFlash('Evenimentul nu a putut fi salvat. Va rugam sa incercati din nou!', 'flash_admin_error');
}
////////
$errors = 'O EROARE';
$this->set(compact('errors'));
}
else
{
// GET ERRORS to display it nicely :)
$errors = $this->Event->invalidFields();
$flash = '';
foreach($errors as $error)
{
$flash .= $error."<br />";
}
$this->Session->setFlash($flash, 'flash_admin_error');
}
I know that there is a way to get rid of form field errors using 'error' => false, but i want to set this for the entire application, thus for all fields in all forms.
It has to be there a way of setting that fot the object itself, and I would be gratefull if someone would tell me.
Thaks a lot!
Edit: This doesn't really disable error output, but will hide the error: go to webroot/css/cake.generic.css add display:none to selector div.error-message. That's the simplest way to achieve what you want that I can think of.
Though it may seem like a bit of an extreme approach to override a single property, you can achieve this by extend the core FormHelper. This will allow you to make Anh Pham's original suggestion the default for all FormHelper instances:
// app/views/helpers/app_form.php
App::import('Helper', 'Time');
class AppFormHelper extends FormHelper {
public $_inputDefaults = array('error' => false);
}
Now to use this as-is in CakePHP 1.3, you would have to use "AppForm" throughout your application to refer to this helper from now on (ie. $this->AppForm->input()). CakePHP 2.0 introduces helper aliasing to overcome this, but for now one has to resort to a bit of trickery to continue using "Form" instead. One blog post I found shows how to backport the functionality and another manages allow the helper to do it itself. I personally use the following without any problems:
// app/views/app.php
class AppView extends View {
function &_loadHelpers(&$loaded, $helpers, $parent = null) {
$return = parent::_loadHelpers($loaded, $helpers, $parent);
# rename App helpers (ie. AppHtml -> Html)
foreach ($return as $helperName => $helper) {
if (substr($helperName, 0, 3) === 'App') {
$newHelperName = substr($helperName, 3);
$return[$newHelperName] = $return[$helperName];
}
}
# done
return $return;
}
}
To use the new created classes above, just add the following to your AppController:
// app/app_controller.php
class AppController extends Controller {
public $helpers = array(/*...*/, 'AppForm');
public $view = array('App');
}
Im building a search function for an application with Lucene.NET and NHibernate.Search. To index the existing data I am using this method:
public void SynchronizeIndexForAllUsers()
{
var fullTextSession = Search.CreateFullTextSession(m_session);
var users = GetAll();
foreach (var user in users)
{
if (!user.IsDeleted)
{
fullTextSession.Index(user);
}
}
}
Where I have marked the fields I want to index with following attribute:
[Field(Index.Tokenized, Store = Store.Yes, Analyzer = typeof(StandardAnalyzer))]
public virtual string FirstName
{
get { return m_firstName; }
set { m_firstName = value; }
}
But when I then inspect the indicies in Luke the fields still have uppercases, commas etc. which should have been removed by the StandardAnalyzer.
Does anyone have know what I am doing wrong?
I had similiar problem to yours, but I've been trying to use WhitespaceAnalyzer. Setting it in Field attribute didn't work for me either.
I've ended up setting it globally. I am using FluentNHibernate for configuration and it looks like that:
this._sessionFactory =
Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005
.ConnectionString(cs => cs
// cut
.ShowSql()
)
.Mappings(m => m.FluentMappings
// cut
)
.ExposeConfiguration(cfg =>
{
// important part: lucene.net and nhibernate.search
cfg.SetProperty("hibernate.search.default.directory_provider", typeof(NHibernate.Search.Store.FSDirectoryProvider).AssemblyQualifiedName);
cfg.SetProperty("hibernate.search.default.indexBase", #"~\Lucene");
cfg.SetProperty("hibernate.search.indexing_strategy", "event");
cfg.SetProperty(NHibernate.Search.Environment.AnalyzerClass, typeof(WhitespaceAnalyzer).AssemblyQualifiedName);
cfg.SetListener(NHibernate.Event.ListenerType.PostUpdate, new FullTextIndexEventListener());
cfg.SetListener(NHibernate.Event.ListenerType.PostInsert, new FullTextIndexEventListener());
cfg.SetListener(NHibernate.Event.ListenerType.PostDelete, new FullTextIndexCollectionEventListener());
})
.BuildSessionFactory();
Take a look at NHibernate.Search.Environment.AnalyzerClass. Funny thing is that it won't work for generic fulltext queries (i think that Lucene will use StandardAnalyzer), but that's another story :).
Hope this helps.
I have a number of FilteringSelect elements within my Zend Framework application that are working fine but they are based on simple queries.
I now need to create a FilteringSelect that will allow me to select the id of one table while displaying the text of field in a related table, i.e. I have two tables groomservices and groomprocedures which are related (i.e. groomprocedures.groomProceduresID has many groomservices.procedure).
The form I'm trying to create is for an appointments table which has many groomservices.groomServicesID values. I want the user to be able to see the name of the procedure while saving the value of the groomservices.groomServicesID using the FilteringSelect.
So far I've not been able to do this in that my FilteringSelect displays nothing, I'm sure this can be done just that the fault is with my inexperience with Zend,Doctrine and Dojo
I'm not sure if my problem is with my autocomplete action(including the query) or with the FilteringSelect element.
Can anyone spot where I've gone wrong in the code sections below, I need to get this working.
My autocomplete action within my controller
public function gserviceAction()
{
// disable layout and view rendering
$this->_helper->layout->disableLayout();
$this->getHelper('viewRenderer')->setNoRender(true);
// get a list of all grooming services IDs and related procedures
$qry= Doctrine_Query::create()
->select('g.groomServicesID,p.groomProcedure')
->from('PetManager_Model_Groomservices g')
->leftJoin('g.PetManager_Model_Groomprocedures p');
$result=$qry->fetchArray();
//generate and return JSON string
$data = new Zend_Dojo_Data('g.groomServicesID',$result);
echo $data->toJson();
}
My FilteringSelect element code
// Create a autocomplete select input for the service
$gservice = new Zend_Dojo_Form_Element_FilteringSelect('gapmtService');
$gservice->setLabel('Proceedure');
$gservice->setOptions(array(
'autocomplete' => true,
'storeID' => 'gserviceStore',
'storeType' => 'dojo.data.ItemFileReadStore',
'storeParams' => array('url' => "/groomappointments/appointment/gservice"),
'dijitParams' => array('searchAttr' => 'groomProcedure')))
->setRequired(true)
->addValidator('NotEmpty', true)
->addFilter('HTMLEntities')
->addFilter('StringToLower')
->addFilter('StringTrim');
Many thanks in advance,
Graham
P.S. orgot to mention I tried the following query in mysql and I gave me what I'm looking for I believe the Doctine query evaluates to the same.
select groomservices.groomservicesID,groomprocedures.groomprocedure from groomprocedures left join groomservices on groomprocedures.groomproceduresID =groomservices.groomProcedure
But I'm not sure if I formatted the query correctly in Doctrine.
EDIT in relation to the flammon's comments
Ok I've set the code to the following but I'm still not getting anything to display.
public function gserviceAction()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContexts(array(
'gservice' => 'json'
));
// get a list of all grooming services IDs and related procedures
$qry= Doctrine_Query::create()
->select('g.groomServicesID AS id,p.groomprocedure AS name')
->from('PetManager_Model_Groomservices g')
->leftJoin('g.PetManager_Model_Groomprocedures p');
$this->view->model = (object) array();
$this->view->model->identifier = 'id';
$this->view->model->label = 'name';
$this->view->model->items = array();
$tableRows = $this->dbTable->fetchAll($qry);
foreach ($tableRows as $row) {
$this->view->model->items[] = $row->toArray();
}
}
I'm sure the fault lies with me.
It looks like there's a problem with the data that you're putting in the ItemFileReadStore.
Here are a few pointers.
Consider extending Zend_Rest_Controller for your services. It'll be easier to manage your contexts and your views. You'll be able to do something like this:
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContexts(array(
'gservice' => 'json'
));
}
And it will eliminate the need for the following in each of you service actions.
// disable layout and view rendering
$this->_helper->layout->disableLayout();
$this->getHelper('viewRenderer')->setNoRender(true);
You'll need to either pass the format parameter or use the following plugin to help with the context switch. Passing the format parameter is simpler but it pollutes the url with ?format=json. Here's the Zend documentation on AjaxContext.
Here's a plugin that you can use if you don't want to pass the format parameter.
class Application_Plugin_AcceptHandler extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
if (!$request instanceof Zend_Controller_Request_Http) {
return;
}
$header = $request->getHeader('Accept');
switch (true) {
case (strstr($header, 'application/json')):
Zend_Registry::get('logger')->log('Setting format to json', Zend_Log::INFO);
$request->setParam('format', 'json');
break;
case (strstr($header, 'application/xml')
&& (!strstr($header, 'html'))):
Zend_Registry::get('logger')->log('Setting format to xml', Zend_Log::INFO);
$request->setParam('format', 'xml');
break;
default:
Zend_Registry::get('logger')->log('Setting format to html', Zend_Log::INFO);
break;
}
}
}
In your controller, instead of echoing the data, create view variables that dojo expects. See this document for the format.
$this->view->model = (object) array();
$this->view->model->identifier = 'id';
$this->view->model->label = 'name';
$this->view->model->items = array();
In your controller, fetch your table rows:
$tableRows = $this->dbTable->fetchAll($select);
or, if you've put model code in a function, it might look more like:
$tableRows = $this->dbTable->fetchGroomProcedures();
Put your row data in the model->items[] array:
foreach ($tableRows as $row) {
$this->view->model->items[] = $row->toArray();
}
Create a view, view/scripts/appointment/gservice.json.phtml and in it put
Zend_Json::encode($this->model)
Use Firebug to see what is returned from your service.