I had this question last week. I found the solution to add and remove related models. But this time i want to make a search.
Database
drugs table
Schema::create('drugs', function (Blueprint $table) {
$table->BigIncrements('id')->unique();
$table->string('name')->unique();
$table->mediumText('info');
$table->timestamps();
});
interactions table
Schema::create('interactions', function (Blueprint $table) {
$table->BigIncrements('id');
$table->string('name');
$table->string('description');
$table->string('category');
$table->timestamps();
});
drug_interaction table
Schema::create('drug_interaction', function (Blueprint $table) {
$table->integer('interaction_id')->unsigned();
$table->foreign('interaction_id')->references('id')->on('interactions');
$table->integer('drug_id')->unsigned();
$table->foreign('drug_id')->references('id')->on('drugs');
$table->timestamps();
});
Models
Drug
class Drug extends Model
{
//Table Name
protected $table = 'drugs';
//Primary Key
public $primaryKey = 'id';
//Timestamps
public $timestamps = true;
public function interactions()
{
return $this->belongsToMany(Interaction::class);
}
}
Interaction
class Interaction extends Model
{
//Table Name
protected $table = 'interactions';
//Primary Key
public $primaryKey = 'id';
//Timestamps
public $timestamps = true;
//Relationship
public function drugs()
{
return $this->belongsToMany(Drug::class);
}
}
InteractionsController
Since edit/update function works properly and kinda' a part of what i look for, i am only adding the update function of conrtoller.
public function update(Request $request, Interaction $interaction)
{
$interaction->name = $request->name;
$interaction->description = $request->description;
$interaction->category = $request->category;
$interaction->save();
$interaction->drugs()->sync($request->drugs);
return redirect('/interactions')->with('success', 'Interaction Updated');
}
The Form to Add Drugs to Interactions
<div class="container">
<div class="row">
<div class="col-md-12">
{!! Form::open(['url' => 'interactions/' . $interaction->id, 'method' => 'patch']) !!}
<div class="form-group">
{{Form::label('name', 'Etkileşim İsmi')}}
{{Form::text('name', $interaction->name, ['class' => 'form-control', 'placeholder' => 'Etkileşim İsmi'])}}
</div>
<div class="form-group">
{{Form::label('description', 'Etkileşim Açıklaması')}}
{{Form::textarea('description', $interaction->description, ['class' => 'form-control', 'placeholder' => 'Etkileşim Bilgisi'])}}
</div>
<div class="form-group">
{{Form::label('category', 'Kategori')}}
{{Form::text('category', $interaction->category, ['class' => 'form-control', 'placeholder' => 'Etkileşim Kategorisi'])}}
</div>
<div class="form-group">
{!! Form::label('İlaçları Seçin') !!}
{!! Form::select('drugs[]', $drugs, null, ['multiple' => 'multiple', 'class' => 'form-control drugs']) !!}
</div>
{{Form::submit('Güncelle', ['class'=>'btn btn-primary'])}}
{!! Form::close() !!}
</div>
</div>
</div>
select2.js
$(document).ready(function() {
$('.drugs').select2({
minimumResultsForSearch: '25',
minimumInputLength: '3',
placeholder: "Etkileşimi olan 2 İlacı Seçiniz."
});
});
SearchController
class SearchController extends Controller
{
public function index()
{
$drugs = Drug::pluck('name','id');
}
I also have the form i used on interaction/create.blade on search.blade:
<div class="col-md-12">
{!! Form::open(['url' => 'getInteraction', 'method' => 'get']) !!}
<div class="form-group">
{!! Form::label('İlaçları Seçin') !!}
{!! Form::select('drugs[]', $drugs, null, ['multiple' => 'multiple', 'class' => 'form-control drugs', 'type' => 'hidden']) !!}
</div>
{!! Form::submit('Ara', ['class' => 'btn btn-danger']) !!}
{!! Form::close() !!}
I couldn't build a query to search the "related interactions" for each selected "drug" , array those interactions and print them only if an interaction_id exists twice in array.
All help is appreciated. Thanks All !
Related
I am trying to upload excel on my db with field matching, i have a working example but now need to develop a little more and am a bit stuck. What I'm confused about is the best way to handle the 2nd import mapping process. After i upload excel file this is my 2nd step https://prnt.sc/d3v1Jk9Ta_-A and the problem if on last field on excel if phone and on the db i need to match with phone_number i get this error
ErrorException
Undefined index: phone_number
But if i match the excel header phone with phone on db the data will be imported and will work fine. How can i fix this problem ? Any idea?
This is my code on import_blade
<table class="min-w-full divide-y divide-gray-200 border">
#if (isset($headings))
<thead>
<tr>
#foreach ($headings[0][0] as $csv_header_field)
{{-- #dd($headings)--}}
<th class="px-6 py-3 bg-gray-50">
<span class="text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">{{ $csv_header_field }}</span>
</th>
#endforeach
</tr>
</thead>
#endif
<tbody class="bg-white divide-y divide-gray-200 divide-solid">
#foreach($csv_data as $row)
<tr class="bg-white">
#foreach ($row as $key => $value)
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
{{ $value }}
</td>
#endforeach
</tr>
#endforeach
<tr>
#foreach ($csv_data[0] as $key => $value)
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
<select name="fields[{{ $key }}]">
#foreach ($db_field as $field)
<option value="{{ (\Request::has('header')) ? $field : $loop->index }}"
#if ($key === $field) selected #endif>{{ $field }}</option>
#endforeach
</select>
</td>
#endforeach
</tr>
</tbody>
</table>
And the controller functions
class ImportController extends Controller
{
public function parseImport(CsvImportRequest $request)
{
if ($request->has('header')) {
$headings = (new HeadingRowImport)->toArray($request->file('csv_file'));
$data = Excel::toArray(new ContactsImport, $request->file('csv_file'))[0];
} else {
$data = array_map('str_getcsv', file($request->file('csv_file')->getRealPath()));
}
if (count($data) > 0) {
$csv_data = array_slice($data, 0, 2);
$csv_data_file = CsvData::create([
'csv_filename' => $request->file('csv_file')->getClientOriginalName(),
'csv_header' => $request->has('header'),
'csv_data' => json_encode($data)
]);
} else {
return redirect()->back();
}
$contact = new Contact;
$table = $contact->getTable();
$db_field = \Schema::getColumnListing($table);
// dd($db_field);
return view('import_fields', [
'headings' => $headings ?? null,
'csv_data' => $csv_data,
'csv_data_file' => $csv_data_file,
'db_field' => $db_field
]);
}
public function processImport(Request $request)
public function processImport(Request $request)
{
// dd($request->fields);
$data = CsvData::find($request->csv_data_file_id);
$csv_data = json_decode($data->csv_data, true);
foreach ($csv_data as $key => $row) {
$contact = new Contact();
$table = $contact->getTable();
$db_field = \Schema::getColumnListing($table);
foreach ($db_field as $index => $field) {
if ($data->csv_header) {
if (array_key_exists($field, $request->fields)) {
$csv_field = $request->fields[$field];
$contact->$field = array_values(array($row[$csv_field]));
}
} else {
if (array_key_exists($index, $request->fields)) {
$csv_field = $request->fields[$index];
$contact->$field = $row[$csv_field];
}
}
}
$contact->save();
}
return redirect()->route('contacts.index')->with('success', 'Import finished.');
}
dd($csv_field); print me this
array:5 [▼
"id" => "id"
"first_name" => "first_name"
"last_name" => "last_name"
"email" => "email"
"phone" => "phone_number"
]
On the first step parseImport i get CSV header and data from import also i get db.table header name (field), and display this data on second step where i need to match the field. But when i match manually a field like screenshot example phone -> phone_number is not working and i get Undefined index: phone_number error
Sorry, very new here to most front end stuff being used here. I have a Kendo Grid, displaying nicely. In my example I have 2 people being displayed in the grid. When I click on the first one, it makes the ajax call, gets the line items, and displays them in an expanded way perfectly. However, when I click on the 2nd person (with person 1 still expanded) it makes the ajax call and gets the data, however, it puts the data under Person1, not person 2, overwriting Person 1's data and leaving person 2's data blank.
<div class="col-lg-12">
<div class="panel panel-default">
#(Html.Kendo().Grid<PersonRollUp>()
.Name("gridview-PersonResults")
.Columns(columns =>
{
columns.Bound(e => e.PersonName).Width(80);
columns.Bound(e => e.NumberNew).Width(50);
columns.Bound(e => e.DollarNew).Width(50);
})
.Sortable()
.Pageable()
.Scrollable()
.ClientDetailTemplateId("headerstemplate")
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Read(read => read.Action("GetPerson", "Controller").Data("persoinRequestData"))
));
<script type="text/x-kendo-tmpl" id="headerstemplate">
#(Html.Kendo().TabStrip()
.Name("tabStrip_detail)
.SelectedIndex(0)
.Animation(animation => animation.Open(open => open.Fade(FadeDirection.In)))
.Items(items =>
{
items.Add().Text("Person Details").Content(#<text>
#(Html.Kendo().Grid<PersonVm>()
.Name("grid_person")
.Columns(columns =>
{
columns.Bound(o => o.Person).Title("Person Name");
columns.Bound(o => o.ShortCode).Title("Loc").Width(80);
columns.Bound(o => o.CustFullName).Title("Customer").Width(180);
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => { model.Id(o => o.Person); })
.PageSize(5)
.Read(read => read.Action("PersonData", "Dashboard", new{ personName = "#=Person#" }).Data("personRequestData")))
.Pageable()
.Sortable()
.PersistSelection()
.ToClientTemplate())</text>);
}).ToClientTemplate())
</script>
</div>
DontVoteMeDown's comment is right - and I do that in my ASP.NET Kendo code when using client detail template grids. You may need to do it for your tabstrip too.
Try updating your tabstrip and grid template code like so:
<script type="text/x-kendo-tmpl" id="headerstemplate">
#(Html.Kendo().TabStrip()
.Name("tabStrip_detail#=Person#") //not sure if you'll have access to Person here, but this ID/Name should be unique if multiple templates can be displayed at the same time
.SelectedIndex(0)
.Animation(animation => animation.Open(open => open.Fade(FadeDirection.In)))
.Items(items =>
{
items.Add().Text("Person Details").Content(#<text>
#(Html.Kendo().Grid<PersonVm>()
.Name("grid_person#=Person#") //Better to use an ID field than name if you have it since the name could have duplicates
.Columns(columns =>
{
columns.Bound(o => o.Person).Title("Person Name");
columns.Bound(o => o.ShortCode).Title("Loc").Width(80);
columns.Bound(o => o.CustFullName).Title("Customer").Width(180);
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => { model.Id(o => o.Person); })
.PageSize(5)
.Read(read => read.Action("PersonData", "Dashboard", new{ personName = "#=Person#" }).Data("personRequestData")))
.Pageable()
.Sortable()
.PersistSelection()
.ToClientTemplate())</text>);
}).ToClientTemplate())
</script>
The checkbox retrieved from database is so long that it is going downwards, is there any way to make it as four layers
when clicked on "all fields" checkbox all checkbox must be checked.
How this to be done?
My code :-
protected function getConfigForm()
{
$sql = 'SELECT id_order_state,name FROM '._DB_PREFIX_.'order_state_lang';
$results = Db::getInstance()->ExecuteS($sql);
$values_query = array(array(
'id' => 'AllFields',
'name' => $this->l('All Fields'),
'val' => 'All',
));
foreach ($results as $row) {
$values_query[] = array(
'id' => 'OrderID',
'name' => $this->l($row['name']),
'val' => $row['id_order_state'],
'required' => true,
);
}
return array(
'form' => array(
'legend' => array(
'title' => $this->l('Settings'),
'icon' => 'icon-cogs',
),
'input' => array(
array(
'type' => 'checkbox',
'label' => $this->l('Select Required Status'),
'required' => true,
'values' => array(
'query' => $values_query,
'id' => 'id',
'name' => 'name'
),
),
),
'submit' => array(
'title' => $this->l('Save'),
),
),
);
}
Admin forms are rendered using /adminXXX/themes/default/template/helpers/form/form.tpl template file.
In classes /classes/helper/Helper.php there's a method createTemplate():
public function createTemplate($tpl_name)
{
if ($this->override_folder) {
if ($this->context->controller instanceof ModuleAdminController) {
$override_tpl_path = $this->context->controller->getTemplatePath().$this->override_folder.$this->base_folder.$tpl_name;
} elseif ($this->module) {
$override_tpl_path = _PS_MODULE_DIR_.$this->module->name.'/views/templates/admin/_configure/'.$this->override_folder.$this->base_folder.$tpl_name;
} else {
if (file_exists($this->context->smarty->getTemplateDir(1).$this->override_folder.$this->base_folder.$tpl_name)) {
$override_tpl_path = $this->context->smarty->getTemplateDir(1).$this->override_folder.$this->base_folder.$tpl_name;
} elseif (file_exists($this->context->smarty->getTemplateDir(0).'controllers'.DIRECTORY_SEPARATOR.$this->override_folder.$this->base_folder.$tpl_name)) {
$override_tpl_path = $this->context->smarty->getTemplateDir(0).'controllers'.DIRECTORY_SEPARATOR.$this->override_folder.$this->base_folder.$tpl_name;
}
}
} elseif ($this->module) {
$override_tpl_path = _PS_MODULE_DIR_.$this->module->name.'/views/templates/admin/_configure/'.$this->base_folder.$tpl_name;
}
if (isset($override_tpl_path) && file_exists($override_tpl_path)) {
return $this->context->smarty->createTemplate($override_tpl_path, $this->context->smarty);
} else {
return $this->context->smarty->createTemplate($this->base_folder.$tpl_name, $this->context->smarty);
}
}
As you can see in this method, you have the possibility to override a default admin template inside your module by creating this file /modules/my_module/views/templates/admin/_configure/helpers/form/form.tpl:
{extends file="helpers/form/form.tpl"}
{block name="input"}
{if $input.type == 'checkbox'}
{if isset($input.expand)}
<a class="btn btn-default show_checkbox{if strtolower($input.expand.default) == 'hide'} hidden{/if}" href="#">
<i class="icon-{$input.expand.show.icon}"></i>
{$input.expand.show.text}
{if isset($input.expand.print_total) && $input.expand.print_total > 0}
<span class="badge">{$input.expand.print_total}</span>
{/if}
</a>
<a class="btn btn-default hide_checkbox{if strtolower($input.expand.default) == 'show'} hidden{/if}" href="#">
<i class="icon-{$input.expand.hide.icon}"></i>
{$input.expand.hide.text}
{if isset($input.expand.print_total) && $input.expand.print_total > 0}
<span class="badge">{$input.expand.print_total}</span>
{/if}
</a>
{/if}
{* HERE WE DEFINE A CHECKBOX CHECK_ALL *}
<input type="checkbox" id="check_all" name="check_all" data-name="{$input.name}" value="1" />
{foreach $input.values.query as $value}
{assign var=id_checkbox value=$input.name|cat:'_'|cat:$value[$input.values.id]}
{* HERE YOU CAN REARRANGE THE CHECKBOXES AS YOU WANT *}
<div class="checkbox{if isset($input.expand) && strtolower($input.expand.default) == 'show'} hidden{/if}">
{strip}
<label for="{$id_checkbox}">
<input type="checkbox" name="{$id_checkbox}" id="{$id_checkbox}" class="{if isset($input.class)}{$input.class}{/if}"{if isset($value.val)} value="{$value.val|escape:'html':'UTF-8'}"{/if}{if isset($fields_value[$id_checkbox]) && $fields_value[$id_checkbox]} checked="checked"{/if} />
{$value[$input.values.name]}
</label>
{/strip}
</div>
{/foreach}
{else}
{$smarty.block.parent}
{/if}
{/block}
{* HERE WE DEFINE THE JAVASCRIPT THAT WILL ANIMATE THE CHECK ALL CHECKBOX *}
<script type="text/javascript">
$("#check_all").on('change', function() {
$("input[name=" + $(this).data('name') + "]").prop('checked', true);
$(this).prop('checked', false);
});
</script>
This template will be used for every admin controller defined in your module.
I didn't test this code, you'll have to adapt it to your needs but the overall concept is here.
I'm getting a very annoying error
Uncaught SyntaxError: Unexpected token u
I have multiple drop down lists, I'm using #Html.DropDownListFor() helper to render it. The error occur as follows:
1- Open one of the drop down list and select an item
2- Open another drop down list then select an item
On step 2 I got the error message but I can't find any thing suspicious or wrong in my code.
Here is how I fill the drop down lists with data (all drop down lists take the same data):
using (Entities context = new Entities())
{
ISDCodes = context.ISDCodes.ToList();
}
ViewBag.ISDCodes = new SelectList(ISDCodes, "ID", typeTextFieldForISDCode);
ISDCode Model:
public partial class ISDCode
{
public int ID { get; set; }
public string CodeEN { get; set; }
public string CodeAR { get; set; }
public string Country { get; set; }
public string PhoneCode { get; set; }
public string Code { get; set; }
}
Here is the Html razor view for these drop down lists:
<div class="form-group clearfix">
<label class="col-sm-2 col-sm-offset-2 control-label">
#Html.LabelFor(model => model.Phone1)
<span class="required">*</span>
</label>
<div class="col-sm-2">
#Html.DropDownListFor(x => x.ISDIDForPhone1, ViewBag.ISDCodes as SelectList, Infas.KFAS.Web.Resources.KFASResources.SelectISDCode,new { id = "ISDIDForPhone1", #class = "form-control" })
</div>
<div class="col-sm-4">
#Html.TextBoxFor(model => model.Phone1, new { #class = "form-control", #maxlength = "12", #onkeypress = "keypress(event)", #type = "number" })
#Html.ValidationMessageFor(model => model.Phone1)
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 col-sm-offset-2 control-label">
#Html.LabelFor(model => model.Phone2)
</label>
<div class="col-sm-2">
#Html.DropDownListFor(x => x.ISDIDForPhone2, ViewBag.ISDCodes as SelectList, Infas.KFAS.Web.Resources.KFASResources.SelectISDCode,new { id = "ISDIDForPhone2", #class = "form-control" })
</div>
<div class="col-sm-4">
#Html.TextBoxFor(model => model.Phone2, new { #class = "form-control", #maxlength = "12", #onkeypress = "keypress(event)", #type = "number" })
#Html.ValidationMessageFor(model => model.Phone2)
</div>
</div>
I am using MVC4 to create a project and in that project I am using jQuery dialog to show pop up to user to edit the data.
When user click on Edit action link it shows a pop up which contains form to edit values of the user.
Edit
This is my code for showing pop up to user.
$('.edit').click(function () {
$.get($(this).data('url'), function (data) {
$('#dialogEdit').dialog({
modal: true,
autoResize: true,
resizable: true,
position: {
my: "center top",
at: "center top",
of: window
},
autoOpen: true,
bgiframe: true,
open: function () {
document.getElementById('dialogEdit').innerHTML = data;
},
close: function () {
document.getElementById('dialogEdit').innerHTML = "";
document.getElementById('dialogEdit').innerText = "";
$("#dialogEdit").empty().hide();
}
});
});
});
This is partial view
#model PITCRoster.ViewModel.LookupTblUserViewModel
#using (Html.BeginForm("SaveChangesResources", "Resources"))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
Html.RenderPartial("_CreateNewResource", Model.tblUser);
Html.RenderPartial("_LookUpDropDowns", Model.LookUpViewModel);
<br />
<input type="submit" value="Save"/>
}
_CreateNewResource.cshtml
#model PITCRoster.tblUser
<fieldset>
<legend>tblUser</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
</fieldset>
_lookupDropDowns.cshtml
#model PITCRoster.ViewModel.LookUpViewModel
#Html.LabelFor(model => model.SelectedLocation)
#Html.DropDownListFor(m => m.SelectedLocation, Model.LocationList, "-Please select-")
#Html.ValidationMessageFor(m => m.SelectedLocation)
#Html.LabelFor(m => m.SelectedStream)
#Html.DropDownListFor(m => m.SelectedStream, Model.StreamList, "-Please select-")
#Html.ValidationMessageFor(m => m.SelectedStream)
#Html.LabelFor(m => m.SelectedDepartment)
#Html.DropDownListFor(m => m.SelectedDepartment, Model.DepartmentList, "-Please select-")
#Html.ValidationMessageFor(m => m.SelectedDepartment)
#Html.LabelFor(m => m.SelectedGlobalLocation)
#Html.DropDownListFor(m => m.SelectedGlobalLocation, Model.GlobalLocationList, "-Please select-")
#Html.ValidationMessageFor(m => m.SelectedGlobalLocation)
I tried using
$('form').removeData('validator');
$('form').removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse('form');
and some more options which were on SO but it didn't help me solve problem.
Can you please help me with this?
Thank you ^_^
You need to ensure that you re-parse the validator after the new content is added to the DOM
$('.edit').click(function () {
$.get($(this).data('url'), function (data) {
$('#dialogEdit').dialog({
....
open: function () {
document.getElementById('dialogEdit').innerHTML = data;
// reparse the validator here
var form = $('form');
form.data('validator', null);
$.validator.unobtrusive.parse(form);
},
....
});
});
});