Doctrine with ZF2 Annotation: how to clear a multi select field? - doctrine-orm

I've got a problem with my multi select fields. Here is the code:
In the Entity class
/**
* #Annotation\Options({ "disable_inarray_validator":"true", "label":"Bound Checkpoints", "target_class":"Checkpoint","property":"name"})
* #Annotation\Type("DoctrineORMModule\Form\Element\EntitySelect")
* #Annotation\Attributes({ "multiple":"true", "class":"form-control"})
* #Annotation\Required(false)
* #ORM\ManyToMany(targetEntity="Checkpoint", inversedBy="affectedByCheckpoints")
*/
private $boundCheckpoints;
public function __construct() {
$this->boundCheckpoints= new \Doctrine\Common\Collections\ArrayCollection();
}
public function addBoundCheckpoints( $items)
{
foreach($items as $item)
{
$this->boundCheckpoints->add($item);
}
}
public function removeBoundCheckpoints($items)
{
foreach($items as $item)
{
$this->boundCheckpoints->removeElement($item);
}
}
My issue is: if I set some stuff into the field, it save it well. If I remove one, still working. But if I remove all items I set and fire the form, the removeBoundCheckpoints method is never called.
I tried to set a required validator to the form, but If I do that, I've got a validation issue.
Any ideas ?

solved by adding this workaround into the template.
{% if field.getAttribute('multiple') == 'multiple' or field.getAttribute('multiple') == 'true' %}
<input type="hidden" name="{{field.getName()}}" value="" />
{% endif %}
{{formElement(field) }}

Related

Why listing of items is empty in calling method of the component?

with livewire 2 I have listing of items ($itemDataRows var) and I need for any item show checkbox ($selectedItems var) and
"Select all" button and clicking on this button all items must be selected. I do :
class CrudItems extends Component
{
private $itemDataRows = [];
public $selectedItems = [];
...
public function render()
{
...
$this->itemDataRows = Item
::orderBy('created_at', 'desc')
...
->paginate($backend_per_page);
return view('livewire.admin.items.crud-items', [
'itemDataRows' => $this->itemDataRows,
'item_rows_count' => $this->item_rows_count
])->layout('layouts.admin');
}
}
public function calcSelectedItemsCount()
{
$ret= 0;
foreach( $this->selectedItems as $next_key=>$next_value ) {
if($next_value) {
$ret++;
}
}
return $ret;
}
public function selectAllItems()
{
$this->selectedItems= [];
\Log::info( dump($this->itemDataRows, ' -0 $this->itemDataRows selectAllItems::') );
// INL OG FILE_I SEE THAT ARRAY ABOVE IS EMPTY!!!
foreach( $this->itemDataRows as $nextItemDataRow ) {
$this->selectedItems[$nextItemDataRow->id] = true;
\Log::info( dump($this->selectedItems, ' -$this->selectedItems INSIDE selectAllItems::') );
}
\Log::info( dump($this->selectedItems, ' -$this->selectedItems selectAllItems::') );
}
and in template :
$selectedItems::{{ var_dump($selectedItems) }}<hr>
$itemDataRows::{{ $itemDataRows }}
/* $selectedItems is filled ok when I click on checkboxes , but $itemDataRows shows empty var, though I filled items listing below */
#foreach ($itemDataRows as $item)
<tr>
<td class=" whitespace-nowrap ">
<x-jet-checkbox id="is_reopen" type="checkbox" class="editor_checkbox_field ml-4" title="On saving editor will be opened"
wire:model="selectedItems.{{ $item->id }}"/>
</td>
Is something wrong with definition of $itemDataRows ? Why $itemDataRows is empty in selectAllItems method, but on my template all items are visible ok....
Thanks in advance!
In Livewire you can pass the data via the class variables. And in the mount function you can fill the variable. For Example.
Important Note: The Class Vars must be public!
public $selectedItems = [];
public function mount(): void
{
$this->selectedItems = ['data' => 'Hello World'];
}
public function render()
{
return view('livewire.admin.items.crud-items')->layout('layouts.admin');
}
Update
This must have something to do with the Livewire Lifecyle. Every Livewire component goes through a lifecycle. Lifecycle hooks allow you to run code at any stage of the component's lifecycle or before updating certain properties. In your case, use the mount hook.
You initialise the variable itemDataRows in the render function. A request then calls the method selectAllItems. There you have to initialise itemDataRows again, because the state is no longer there during render or mount.
Solution: create a method getItemDataRows()
private getItemDataRows()
{
$this->itemDataRows => Item::orderBy('created_at', 'desc')
...
->paginate($backend_per_page);
}
then you can call those in the render method and in the selectAllItems method too.
public function selectAllItems()
{
$this->selectedItems= [];
$this->itemDataRows => $this->getItemDataRows();
...
// your code
}

NullReferenceException while passing list of object from view to controller

I am trying to save list of object from view to controller but i am getting NullReferenceException when list is more that 25. It works fine if list less than 25.
public async Task<IActionResult> ImportStudentExcel(IFormFile file)
{
var list = new List<StudentImport>();
//Here it contains logic for adding item to list from excel file
ViewBag.FileName = file.FileName;
return View(list.ToList());
}
I am getting all the item in my view
I am doing this to bind properties
//Containes Table for Showing List
<form id="saveForm" asp-action="SaveFromImport" asp-controller="StudentImport" method="POST">
<input type="hidden" name="filename" value="#ViewBag.FileName">
#for(int i=0; i<Model.Count; i++)
{
<input asp-for="#Model[#i].Fullname" type="hidden" value="#Model[#i].Fullname"/>
<input asp-for="#Model[#i].Gender" type="hidden" value="#Model[#i].Gender"/>
<input asp-for="#Model[#i].DOB" type="hidden" value="#Model[#i].DOB"/>
// Other 15 Properties Like Address, PhoneNumber, RegNo etc
}
<input type="submit" value="Save">
</form>
When I inspect this page all item are present
public async Task<IActionResult> SaveFromImport(List<StudentImport> students, string filename)
{
try
{
foreach (var t in students)
{
System.Console.WriteLine(t.Fullname);
//Save to DB
}
}
catch (Exception e)
{
System.Console.WriteLine(e.ToString());
}
return RedirectToAction("Index", "Student");
}
Am getting NullReference at foreach Statement. I dont know whats going on. It works as expected when list count is 13 but wont work when count is 25 or more, It also works when there is only one property in StudentImportModel and count is sttil 25.
The ExceptionMessage in my case was NullReferenceException but the actual error was InvalidDataException: Form value count limit 1024 exceeded.
However, I managed to solve this by adding this code in ConfigureServices method.
services.Configure<FormOptions>(options =>
{
options.ValueCountLimit = 6000;
});

model class is not working in laravel project

i am beginner in la-ravel,problem in work on model how be work on project.
firstly used the api.php to link the page
Route::any('/user',['uses'=>'PagesController#my']);
create the controller
public function my(Request $request){
$val=validator::make($request->all(),[
'id'=>'required',
'name'=>'required',
'email'=>'required',
'mobile'=>'required'
]);
//return 'rahul';
return response()->json([$val]);
}
model is link to the controller
use App\rahul;
use Validator;
create the model page design
class rahul extends Model{
protected $table = "display";
public function my($data)
{
$save = new rahul;
$save->id = $data['id'];
$save->name = $data['name'];
$save->email = $data['email'];
$save->mobile = $data['mobile'];
$save->save();
return $save->id;
}
}
and,last step will done it create the database like
enter image description here
database name is lara2 and table name display simple page design
but problem how to model be used
Route::get('first', 'ApiController#first')->name('first');
Route::post('store', 'ApiController#store')->name('store');
using the code in api.php
and next step model is create
php artisan make: model Article
model page
class Article extends Model{ protected $fillable = ['name', 'email'];}
next step create the controller
controller page (apicontroller)
public function first(){
return view('first');
}
public function store(Request $request)
{
$article = Article::create($request->all());
return response()->json($article, 201);
}
blade page web page design
<form method="POST" action="store">
{{csrf_field()}}
<input type="text" name="name">
<input type="email" name="email">
<input type="submit" name="submit"></form>
migration is create Article table name connection
public function up()
{
Schema::create('Articles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('Articles');
}

Many To Many friendlist with symfony 3

I want to make a friendlist using ManyToMany self-referencing.
I followed this link and it seemms to be good. But Now, what Action should I have in my controller to :
1- get All myFriends / or all all friend of current user
2- add a firend, using a link such as "Add friend"
thank you for your time and answers
in your link my friends is a doctrine array collection, to get the friends of a user just iterate on it and to add a friend just add a friend onto this collection and save the entity (with the entity manager), maybe you ll need to add a cascade persist on the collection to add a new user as friend.
you have to add some methods like getMyFriends, addFriend and removeFriend
<?php
/** #Entity */
class User
{
// ...
/**
* Many Users have Many Users.
* #ManyToMany(targetEntity="User", mappedBy="myFriends")
*/
private $friendsWithMe;
/**
* Many Users have many Users.
* #ManyToMany(targetEntity="User", inversedBy="friendsWithMe")
* #JoinTable(name="friends",
* joinColumns={#JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="friend_user_id", referencedColumnName="id")}
* )
*/
private $myFriends;
public function __construct() {
$this->friendsWithMe = new \Doctrine\Common\Collections\ArrayCollection();
$this->myFriends = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getMyFriends(){
return $this->myFriends;
}
public function addFriend(User $friend){
$this->myFriends->add($friend);
}
public function removeFriend(User $friend){
$this->myFriends->removeElement($friend);
}
}
in your controller you have to implement an action with
$currentUser= $this->get('security.context')->getToken()->getUser();
$myFriends = $currentUser->getMyfriends();
$this->render('your-template.html.twig', array(
'myFriends' => $myFriends,
));
and in your twig template
<h1>My friends</h1>
<ul>
{% for friend in myFriends %}
<li>{{ friend.username }}</li>
{% endfor %}
</ul>

MVC 4 - sorting with LINQ doesn't work with Ajax.BeginForm and my For loop

I writing some code with C# and MVC and I have button for sorting a list of data by asc and desc. The logic works in my controller, I am able to call the method that sorts the list and in the breakpoint I can see that it has been sorted.
But it's weird because when I loop through my list in the partial view it never works. I use a breakpoint in my view to make sure it's the same order of items which it is. But it's like the new values don't render to the screen.
TeamManagement.cshtml
#model Website.Models.modelTeamSelect
#{
ViewBag.Title = "Football App";
}
#section featured {
}
#using (Ajax.BeginForm("_PartialTeams",
new
{
model = this.Model
},
new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "divCreatedTeams",
InsertionMode = InsertionMode.Replace
}))
{
<div id="divTeams" style="float: left; padding: 10px;">
<h3>Create a new team:</h3>
#Html.LabelFor(m => m.team.TeamName)
#Html.TextBoxFor(m => m.team.TeamName)
<input type="submit" value="Add Team" name="btnSubmit" />
</div>
Html.RenderPartial("~/Views/Partials/_PartialTeams.cshtml");
}
_PartialTeams.cshtml
#model Website.Models.modelTeamSelect
<div id="divCreatedTeams" style="float: left; padding: 10px;">
<h3>Your created teams:</h3>
<input type="submit" value="Asc" name="btnSubmit" />
<input type="submit" value="Desc" name="btnSubmit" />
<br />
#if (Model.teams.Count > 0)
{
for (int i = 0; i < Model.teams.Count; i++)
{
#Html.EditorFor(m => m.teams[i].TeamName)
<input type="button" value="Update team name" name="btnSubmit"/>
<input type="button" value="Remove team" name="btnSubmit"/>
<br />
}
}
</div>
Sorting logic in my controller
[HttpPost]
public PartialViewResult _PartialTeams(string BtnSubmit, modelTeamSelect modelTeamSelect)
{
switch (BtnSubmit)
{
case "Add Team":
modelTeamSelect.teams.Add(modelTeamSelect.team);
break;
case "Asc":
FootballRepository = new Repository.FootballRepository();
modelTeamSelect.teams = FootballRepository.Sort(modelTeamSelect, BtnSubmit);
break;
case "Desc":
FootballRepository = new Repository.FootballRepository();
modelTeamSelect.teams = FootballRepository.Sort(modelTeamSelect, BtnSubmit);
break;
}
return PartialView("~/Views/Partials/_PartialTeams.cshtml", modelTeamSelect);
}
public List<Models.modelTeam> Sort(Models.modelTeamSelect modelTeamSelect, string sort)
{
switch (sort)
{
case "Asc":
modelTeamSelect.teams = modelTeamSelect.teams.OrderBy(t => t.TeamName).ToList();
break;
case "Desc":
modelTeamSelect.teams = modelTeamSelect.teams.OrderByDescending(t => t.TeamName).ToList();
break;
}
return modelTeamSelect.teams;
}
My main model with team collection
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Website.Models
{
public class modelTeamSelect
{
public modelTeamSelect()
{
teams = new List<modelTeam>();
team = new modelTeam();
}
public List<modelTeam> teams { get; set; }
public modelTeam team { get; set; }
}
}
My method Sort does it's job but in the view it never displays correctly. e.g. always wrong order.
Anyone have any ideas because I am stuck.
Screenshots
In the screenshots I click sort by Asc and you can see it says Newcastle as the first item in the list. But when the page renders it will say West Ham first even though it is iterating using the for loop.
All the Html helpers are preferring to use the ModelState values over the actual model values.
So even you have sorted in place your modelTeamSelect.teams in your action in the view #Html.EditorFor(m => m.teams[i].TeamName) call will use the original (before sorting) values form the ModelState.
The solution: if you are updating your action parameters in-place then just clear the ModelState before returning the View/PartialView:
[HttpPost]
public PartialViewResult _PartialTeams(string BtnSubmit,
modelTeamSelect modelTeamSelect)
{
// ... Do the sorting, etc.
ModelState.Clear();
return PartialView("~/Views/Partials/_PartialTeams.cshtml", modelTeamSelect);
}
You can read more about why the helpers are working like this in this article: ASP.NET MVC Postbacks and HtmlHelper Controls ignoring Model Changes