CodeIgniter 4 - Draw Inputs added dynamically by jQuery after submitting the Form with validation Error - codeigniter

i have a page to define the expenses in my system, when click on add (+) button jQuery function will draw new empty line(s), inputs name (title_en_new[],title_ar_new[],account_numer_new[],prefix_new[])
after submitting the form when click , validation run as below
$validationRules = [
'title_en_new.*' => ['rules'=>"required|max_length[255]",'label'=>lang('Global.englishName')],
'title_ar_new.*' => ['rules'=>"required|max_length[255]",'label'=>lang('Global.arabicName')],
'account_number_new.*' => ['rules'=>"trim_null|max_length[50]",'label'=>lang('Global.AccountNumber')],
'prefix_new.*' => ['rules'=>"required|max_length[30]",'label'=>lang('Global.prefix')],
];
//$picture = $this->request->isValid('picture');
if (!$this->validate($validationRules)) {
return redirect()->to('/Setup/ExpensesTypes')->withInput()->with('validation', $this->validator->getErrors());
}
then how to redraw the new added inputs that have validation error?
note : i tried to use $this->request->getPost() in expenses view, but error appeared (undefined property $inputs).
i tried to use
1- session('validation'), but this array contains the error input only not hall the inputs in same line.
2- setvalue(), but here to loop from 1 to lines count form and check if exist in session('validation') also. and its complicated.

Related

Kendo TreeView in grid display 'undefined'

I had this kendo grid demo, and on outletID column, i want to use kendoTreeView with checkbox, so multiple selected outletID possible. But when edit it display undefined result, and the template that display outletName also not working. Appreciate your help
DEMO IN DOJO
Your tree needs dataTextField and dataValueField set.
Your column template doesn't know where to look for the outletName. Kendo supports 1-N relationships, but I'm not aware of N-N.
The data in your template is the current row of the grid. For the first row, that would be {"id":"1","outletID":"LA2,LA3","accountName":"Data1"}. You need to process that data yourself. For instance:
template: "#= (data.outletID) ? data.outletID.split(',')
.map(x => TreeData.find(y => y.outletID == x)['outletName']) : '' #"
For the editor, the value of a dropDownTree is an array. Your row has a string. You need to do two things:
1 . Init the editor's value in the function outletTree:
if (options.model) {
ddt.value((options.model[options.field] || '').split(','))
}
2 . When the dropDownTree's value changes, update your grid row:
change: e => {
const value = e.sender.value();
console.log(value)
options.model.set(options.field, value.join(','))
}
Here's an updated dojo: https://dojo.telerik.com/#GaloisGirl/oYEGerAK . The "Update" button doesn't work yet, probably because the dataSource must support edition. Here is how to do it on local data.

Kendo Scheduler Scrape Recurrence Rule Before Save

I have a custom edit template for kendo scheduler.
Below all the controls to set dates and the recurrence rule I have a button.
Pressing the button loads a list of people available for that appointment.
To get that list, I am checking conflicts in future visits and I'm checking against a people availability table to make sure they are available on those dates.
All the code works fine except I cannot get the recurrence rule before the Save button is pressed and the data is transported to the server.
The recurrenceRule property is blank even though all the selections are made before pressing my button.
It seems kendo scheduler formats that recurrence rule when you press the save button and then populates the model and transports it to the server.
I could write my own Recurrence Rule by reading the widgets in the kendo recurrence editor control but they didn't put an Id's on the widgets which makes them hard to get. I think you can use css selectors but I haven't done anything like that and would rather not write my own recurrence editor.
Does anyone know how to get the recurrence rule while in the edit template before pressing Save?
FLOW:
1) set start and end date, and recurrence pattern in kendo recurrence editor
2) press button on edit template form to load available employees
--- I need the recurrence rule here.
On the server side I expand the appointment to all it's occurrences
and then I check each potential visit against the employee schedule
3) select one of the employees and save the record.
--- I can't do the check here because the employee has to be selected before saving the record and I only want to provide a list of available employees -- before save.
I tried many things including this:
var recurEditor = $("#RecurrenceRule").data("kendoRecurrenceEditor");
var recurrenceRule = recurEditor.options.recurrenceRule;
alert("recurrenceRule: " + recurrenceRule);
But no luck...
Here's the solution. I knew if I posted the question here, after 2 days of trying to figure it out, that I'd find the solution. Maybe this will help someone else.
On the handler for my button to load available employees, I have this code:
var ruleEditor = $('[id="RecurrenceRule"]').getKendoRecurrenceEditor();
if (ruleEditor) {
vRecurRuleValue = ruleEditor.value();
alert("vRecurRuleValue = " + vRecurRuleValue);
}
My recurrence editor is defined in my edit template as so:
#(Html.Kendo().RecurrenceEditorFor(model => model.RecurrenceRule).HtmlAttributes(new { data_bind = "value:recurrenceRule", data_role = "recurrenceEditor" } ))
And my employee dropdown has a filter as follows:
<div id="EmpAssignedDropdownlist" class="k-edit-field" style="visibility:hidden;">
#(Html.Kendo().DropDownListFor(m => m.VisitEmployeeM.UserId)
.AutoBind(false)
.Text("Please Select") //used to prevent initial datasource.read as AutoBind doesn't work
.DataTextField("name")
.DataValueField("id")
.ValuePrimitive(true)
.OptionLabel(#Localizer["Please Select"].Value)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetEmployeesAvailableForPotentialVisit", "DropDownList").Data("filterAvailableEmployeesNoVisitYet");
}).ServerFiltering(true);
})
)
</div>
the javascript function "filterAvailableEmployeesNoVisitYet" passes the recurrence rule and other data I need to check for conflicts and loads the dropdownlist.

Simple pagination in datatable using ajax without sending total count from server

I'm using DataTables 1.10.5. My table uses server side processing via ajax.
$('#' + id).dataTable({
processing: true,
serverSide: true,
ajax: 'server-side-php-script-url',
"pagingType": "simple_incremental_bootstrap"
});
Everything will work properly if I send 'recordsTotal' in the server response. But I don't want to count the total entries because of performance issues. So I tried to use the pagination plugin simple_incremental_bootstrap. However it is not working as expected. The next button always return the first page itself. If I give 'recordsTotal' in server response this plugin will work properly. I found out that If we don't give 'recordsTotal', the 'start' param sent by datatable to server side script is always 0. So my server side script will always return the first page.
According to this discussion, server side processing without calculating total count is not possible because “DataTables uses the record count that is passed back to it to deal with the paging controls”. The suggested workaround is “So the display records are needed, but it would be possible to just pass back a static number (like 1'000'000 or whatever) which would make DataTables think there are a million rows. You could hide the information element if this information is totally bogus!”
I wonder if anybody have a solution for this. Basically I want to have a simple pagination in my datatable with ajax without sending total count from server.
A workaround worth to try..
If we don't send recordsTotal from server, the pagination won't work properly. If we send a high static number as recordsTotal, table will show an active Next button even if there is no data in next page.
So I ended up in a solution which utilizes two parameters received in ajax script - 'start' and 'length'.
If rows in current page is less than 'limit' there is no data in next page. So total count will be 'start' + 'current page count'. This will disable Next button in the last page.
If rows in current page is equal to or greater than 'limit' there is more data in next pages. Then I will fetch data for next page. If there is at least one row in next page, send recordsTotal something larger than 'start + limit'. This will display an active Next button.
Sample code:
$limit = require_param('length');
$offset = require_param('start');
$current_page_data = fn_to_calculate_data($limit, $offset); // in my case, mysqli result.
$data = “fetch data $current_page_data”;
$current_page_count = mysqli_num_rows($current_page_data);
if($current_page_count >= $limit) {
$next_page_data = fn_to_calculate_data($limit, $offset+$limit);
$next_page_count = mysqli_num_rows($next_page_data);
if($next_page_count >= $limit) {
// Not the exact count, just indicate that we have more pages to show.
$total_count = $offset+(2*$limit);
} else {
$total_count = $offset+$limit+$next_page_count;
}
} else {
$total_count = $offset+$current_page_count;
}
$filtered_count = $total_count;
send_json(array(
'draw' => $params['draw'],
'recordsTotal' => $total_count,
'recordsFiltered' => $filtered_count,
'data' => $data)
);
However this solution adds some load to server as it additionally calculate count of rows in next page. Anyway it is a small load as compared to the calculation total rows.
We need to hide the count information from table footer and use simple pagination.
dtOptions = {};
dtOptions.pagingType = "simple";
dtOptions.fnDrawCallback = function() {
$('#'+table_id+"_info").hide();
};
$('#' + table_id).dataTable(dtOptions);

How do I Dynamically show the pageSize in yii2?

For now I have set static pagesize in my search function, but now I need to create dropdown for user to change the pagesize from front end. For e.g like 10,20,50,100.
I got the code but it is for yii previous version.
If I had to do it I will use the following approach.
Create a Dropdown for the page sizes, you can adjust the dropdown inside the layout option of the gridview if you want it between summary text and items list or add it before the gridview. like this image, you can wrap it with div to adjust the CSS for it yourself.
The main thing to do is to include the id of the drop-down to the filterSelector option so that every time the gridview is filtered the dropdown value is also submitted and also whenever you change the dropdown.
Your GridView will look like below
GridView::widget([
'dataProvider' => $dataProvider,
'layout'=>'{summary}'.Html::activeDropDownList($searchModel, 'myPageSize', [1 => 10, 2 => 20, 50 => 50, 100 => 100],['id'=>'myPageSize'])."{items}<br/>{pager}",
'filterModel' => $searchModel,
'filterSelector' => '#myPageSize',
'columns'=>[
// your column configurations.......
]
]);
Declare a public property in the searchModel
public $myPageSize
Add that property to the safe rules inside your searchModel
[['myPageSize'],'safe']
And then update you search() method inside the relative SearchModel you are using with the GridView. You should assign the pageSize option of the query inside the $dataProvider with the new property defined but make sure you add this line after the $this->load($params) statement.
See below
$dataProvider->pagination->pageSize = ($this->myPageSize !== NULL) ? $this->myPageSize : 10;`
Here we are setting the default page size equal to the minimum option inside the drop-down we created, otherwise it would be updated when ever you change the dropdown.
Now try changing the dropdown you will see it working. Hope this helps
Thank you Muhammad!
Your answer helped me, but on the layout I had to modify the array for the select:
Where you have "1 => 10, 2 => 20," I had to change it to "10 => 10, 20 => 20,". Otherwise it pagination goes one by one or two by two.
It ended up like this:
'layout'=>'{summary}'.Html::activeDropDownList($searchModel, 'myPageSize', [10 => 10, 20 => 20, 50 => 50, 100 => 100],['id'=>'myPageSize'])."{items}<br/>{pager}",
The rest worked perfect!

Populating dropdown list with two columns from database

I'm working on MVC3 project.
At my controller I already have a code that gets the Descr column from StockClass table. After that I fill a ViewBag with this list in order to retrieve it from the view and populate the dropdown list.
Currently is working fine but only shows Descr field (obviously). What i want is populate the dropdown list with two fields (Code and Descr) in this format: "code - descr".
I tried several ways but i cannot find the way to code the #Html helper correctly.
In my controller...
var oc = dba.StockClass.OrderBy(q => q.Code).ToList();
ViewBag.OrderClass = new SelectList(oc, "StockClassId", "Descr");
In my view....
#Html.DropDownList("StockClassID", (SelectList)ViewBag.OrderClass)
Could you please help me?
I don't believe there is an HTML Helper which will do that for you, but you can get what you're after like this:
var oc = dba.StockClass
.OrderBy(q => q.Code)
.ToDictionary(q => q.StockClassId, q => q.Code + " - " + q.Descr);
ViewBag.OrderClass = new SelectList(oc, "Key", "Value");
This also has the advantage of making the uses of StockClassId, Code and Descr refactor-friendly - if you rename those properties you won't be able to compile without updating this bit of code to match.

Resources