I am working on a laravel project.I have uploaded image using ajax in database and to the local "public/images" folder as well.But i can not show the image without refreshing my page.Some mistake in response success function.Can anyone help me out?
success:function(data)
{
$('.error').remove();
$('#table').append("<tr class='post" + data.id + "'>"+
"<td>" + data.id + "</td>"+
"<td>" + data.name + "</td>"+
"<td>" + data.bank_name + "</td>"+
"<td>" + data.bankbranch_location + "</td>"+
"<td>" + data.image + "</td>"+
"<td>" + data.created_at + "</td>"+
"<td><button class='show-modal btn btn-info btn-sm' data-id='" + data.id + "' data-bank_id='" + data.bank_name + "' data-bankbranch_id='" + data.bankbranch_location + "' data-name='" + data.name + "' data-phone='" + data.phone + "'><span class='fa fa-eye'></span></button> <button class='edit-modal btn btn-warning btn-sm' data-id='" + data.id + "' data-bank_id='" + data.bank_name + "' data-bankbranch_id='" + data.bankbranch_location + "' data-name='" + data.name + "' data-phone='" + data.phone + "'><span class='glyphicon glyphicon-pencil'></span></button> <button class='delete-modal btn btn-danger btn-sm' data-id='" + data.id + "' data-bank_id='" + data.bank_name + "' data-bankbranch_id='" + data.bankbranch_location + "' data-name='" + data.name + "' data-phone='" + data.phone + "'><span class='glyphicon glyphicon-trash'></span></button></td>"+
"</tr>");
}
When you res you should use show image
success:function(data)
{
$('.error').remove();
let html = `
<tr class='post${data.id}'>
<td>${data.id}</td>
<td>${data.name}</td>
<td>${data.bank_name}</td>
<td><img src="path/to/${data.image}" alt=""></td>
<td>${data.created_at}</td>
<td>
<div data-id='${data.id}' data-bank_id='${data.bank_name}' data-bankbranch_id='${data.bankbranch_location}'
data-name='${data.name}' data-phone='${data.phone}'>
<button class='show-modal btn btn-info btn-sm'> <span class='fa fa-eye'></span> </button>
<button class='edit-modal btn btn-warning btn-sm'><span class='glyphicon glyphicon-pencil'></span></button>
<button class='delete-modal btn btn-danger btn-sm'><span class='glyphicon glyphicon-trash'></span></button>
</div>
</td>
</tr> `;
$('#table').append(html);
}
This is my controller from where the data is saved in database and in a local folder called "images" and giving a response to the ajax function with these datas
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
if ($validator->passes()) {
$input = $request->all();
$input['image'] = time().'.'.$request->image->getClientOriginalExtension();
$request->image->move(public_path('images'), $input['image']);
$employee= Employee::create($input);
return response()->json($employee);
}
return response()->json(['error'=>$validator->errors()->all()]);
}
You need to insert the data.image inside the src attribute of image tag.
"<td>" + <img src='/yourpath/' + data.image + "> </td>"
For Public path in Laravel use:
"<td>" + <img src='{{ URL::asset('images/') }}' +'/' + data.image + "> </td>"
Related
I am using ajax to get some students data from database. And I have separate markup inside ajax for that data to display in the table. Now what I wanna do is to get the last inserted record or the latest record on the top but I have no I idea how to do that. I use sortByDesc() function but that does not work in this case. Below is my code. Help :)
Ajax Call
var classID = $(this).val();
if (classID) {
$.ajax({
url: '/attendance/ajax/' + classID,
type: "GET",
dataType: "json",
success: function (data) {
var table = $('table[id="studentsData"]');
table.DataTable().destroy();
var markup = '';
markup = '<thead><tr><th style="width: 2%" class="align-middle text-center"><input type="checkbox" id="options"></th><th style="width: 15%" class="text-center">Student ID</th> <th style="width: 15%" class="text-center">Student Name</th> <th style="width: 15%" class="text-center">Attendance</th> <th style="width: 15%" class="text-center">Date</th> <th style="width: 15%;" class="align-middle text-center">Actions</th> </tr></thead><tbody>';
$.each(data, function (key, value) {
markup += '<tr> <td><input class="checkBoxes" type="checkbox" name="checkBoxArray[]" value="' + value.id + '"></td> <td class="text-center align-middle"><input type="hidden" value="' + value.student_id + '" name="student_id[]">' + value.student_id + '</td> <td class="text-center align-middle"><input type="hidden" value="' + value.first_name + '" name="first_name[]"><input type="hidden" value="' + value.last_name + '" name="last_name[]">' + value.first_name + ' ' + value.last_name + '<td class="text-center align-middle"><input type="hidden" value="' + value.attendance + '" name="attendance[]">' + value.attendance + '</td>' + '<td class="text-center align-middle"><input type="hidden" value="' + value.date + '" name="date[]">' + value.date + '</td>' + '<td style=" width=12%" class="text-center"> <a data-toggle="modal" data-target="#editAttendanceModal' + value.id + '"><button title="Edit" class="btn btn-primary"><span class="fas fa-pencil-alt"></span></button></a> <a data-toggle="modal" data-target="#deleteAttendanceModal' + value.id + '"><button title="Delete" class="btn btn-danger"><span class="fas fa-trash-alt"></span></button></a> </td>' + '</td> </tr>';
});
markup += '</tbody>';
var table = $('table[id="studentsData"]');
table.html(markup);
table.DataTable();
}
});
}
});
**Controller**
public function myAttendanceAjax($id) {
$students_register = StudentsAttendance::where('class_id', $id)->get();
return json_encode($students_register);
}
You can use orderBy('id', 'desc')->get(); for geting latest record.
There is a method latest() defined in Illuminate\Database\Query\Builder Class.
public function latest($column = 'created_at')
{
return $this->orderBy($column, 'desc');
}
So, It will just orderBy with the column you provide in descending order with the default column will be created_at.
For more information about sorting have a look at https://laravel.com/docs/5.8/queries#ordering-grouping-limit-and-offset
These are my databases, where a division can have many districts (division_id is the foreign key in districts table).
When I submit the modal (using Ajax with laravel) the division name comes as undefined.
However, after I refresh the browser, everything seems to be working okay. Why is this happening and how do I fix it?
This is the code I am using to show the data.
{{ csrf_field() }}
<?php $no=1; ?>
#foreach ($district as $district)
<tr class="post{{$district->id}}">
<td>{{ $no++ }}</td>
<td>{{ $district->division->name}}</td>
<td>{{ $district->code}}</td>
<td>{{ $district->name}}</td>
<td>{{ $district->created_at}}</td>
<td>
<a href="#" class="show-modal btn btn-info btn-sm" data-id="{{$district->id}}" data-division_id="{{$district->division->name}}" data-code="{{$district->code}}" data-name="{{$district->name}}" >
<i class="fa fa-eye"></i>
</a>
<a href="#" class="edit-modal btn btn-warning btn-sm" data-id="{{$district->id}}" data-division_id="{{$district->division->name}}" data-code="{{$district->code}}" data-name="{{$district->name}}" >
<i class="glyphicon glyphicon-pencil"></i>
</a>
<a href="#" class="delete-modal btn btn-danger btn-sm" data-id="{{$district->id}}" data-division_id="{{$district->division->name}}" data-code="{{$district->code}}" data-name="{{$district->name}}" >
<i class="glyphicon glyphicon-trash"></i>
</a>
</td>
</tr>
#endforeach
This is my controller.
use Illuminate\Http\Request;
use App\Division;
use App\District;
use Validator;
use Response;
use Illuminate\Support\Facades\Input;
use App\http\Requests;
class DistrictController extends Controller
{
public function index()
{ $district = District::all();
$divisionDistricts = Division::pluck('name','id');
return view('masterForms.district',compact('district','divisionDistricts'));
}
public function store(Request $request)
{
if($request->ajax())
{
$district = District::create($request->all());
$district->save();
return response($district);
}
}
This is my District Model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Division;
class District extends Model
{
protected $fillable = ['code','name','division_id'];
public function division()
{
return $this->belongsTo(Division::class);
}
}
?>
And this is the javaquery I am using to add my data to the database.
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="token"]').attr('content')
}
});
$(document).on('click','.create-modal', function() {
$('#create').modal('show');
$('.form-horizontal').show();
$('.modal-title').text('Add District');
});
$('#ddistrict').on('submit',function(e){
e.preventDefault();
var data = $(this).serialize();
var url = $(this).attr('action');
var post = $(this).attr('method');
$.ajax({
type: post,
url: url,
data: data,
dataTy: 'json',
success:function(data)
{
$('.error').remove();
$('#table').append("<tr class='post" + data.id + "'>"+
"<td>" + data.id + "</td>"+
"<td>" + data.division_id.name + "</td>"+
"<td>" + data.code + "</td>"+
"<td>" + data.name + "</td>"+
"<td>" + data.created_at + "</td>"+
"<td><button class='show-modal btn btn-info btn-sm' data-id='" + data.id + "' data-division_id.name='" +
data.division_id.name + "' data-code='" +
data.code + "' data-name='" +
data.name + "'><span class='fa fa-eye'></span></button> <button class='edit-modal btn btn-warning btn-sm' data-id='" + data.id +"' data-division_id.name='" +
data.division_id.name + "' data-code='" +
data.code + "' data-name='" +
data.name + "'><span class='glyphicon glyphicon-pencil'></span></button> <button class='delete-modal btn btn-danger btn-sm' data-id='" + data.id + "' data-division_id.name='" +
data.division_id.name + "' data-code='" +
data.code + "' data-name='" +
data.name + "' ><span class='glyphicon glyphicon-trash'></span></button></td>"+
"</tr>");
}
});
})
</script>
Just returning $disrtict will just give you division_id not division name. And you can't use data.division_id.name in your javascript.
To return division you must append division name with your other attributes of districts. Or you might use Api Resources to provide your custom json response.
To append division name attribute in you district you should use $appends variable.
class District extends Model
{
protected $appends = ['division_name'];
protected $fillable = ['code','name','division_id'];
public function division()
{
return $this->belongsTo(Division::class);
}
public function getDivisionNameAttribute(){
return $this->division->name;
}
}
Now in your ajax resopnse use
success:function(data)
{
$('.error').remove();
$('#table').append("<tr class='post" + data.id + "'>"+
"<td>" + data.id + "</td>"+
"<td>" + data.division_name + "</td>"+
"<td>" + data.code + "</td>"+
"<td>" + data.name + "</td>"+
"<td>" + data.created_at + "</td>"+
"<td><button class='show-modal btn btn-info btn-sm' data-id='"+ data.id + "' data-division_id='" +
data.division_name + "' data-code='" +
data.code + "' data-name='" +
data.name + "'><span class='fa fa-eye'></span></button> <button class='edit-modal btn btn-warning btn-sm' data-id='" + data.id +"' data-division_id.name='" +
data.division_name + "' data-code='" +
data.code + "' data-name='" +
data.name + "'><span class='glyphicon glyphicon-pencil'></span></button> <button class='delete-modal btn btn-danger btn-sm' data-id='" + data.id + "' data-division_name='" +
data.division_name + "' data-code='" +
data.code + "' data-name='" +
data.name + "' ><span class='glyphicon glyphicon-trash'></span></button></td>"+
"</tr>");
}
Hello can someone please help me because I wanted to use ajax in my laravel form, when everytime I hit 'CREATE POST' button, the table contains all my posts will hide and then the form will show, and when clicking the submit button in the form the table will then show with its new data inserted below the table and the form will hide. I have a code but it is not working.
Controller Code:
public function store(Request $request)
{
//validate the data
$this->validate($request, array(
'title' => 'required|max:255',
'slug' => 'required|alpha_dash|min:5|max:255|unique:posts,slug',
'category_id' => 'required|integer',
'body' => 'required',
'featured_image' => 'image|nullable|max:1999'
));
//store in the database
$post = new Post;
$post->title = $request->title;
$post->slug = $request->slug;
$post->category_id = $request->category_id;
$post->body = Purifier::clean($request->body);
//Save Our Image
if ($request->hasFile('featured_image')) {
$image = $request->file('featured_image');
$filename = time() . '.' . $image->getClientOriginalExtension();
$location = public_path('images/'. $filename);
Image::make($image)->resize(800, 400)->save($location);
$post->image = $filename;
}
$post->save();
return response()->json($post);
// Session::flash('success', 'The blog post was succesfully saved!');
// //redirect to another page
// return redirect()->route('posts.show', $post->id);
}
Route:
Route::resource('/posts', 'PostController');
Route::post('/addpost', 'PostController#store');
Form Code:
{!! Form::open(['id' => 'form-post', 'method' => 'POST', 'route' => 'posts.store', 'data-parsley-validate' => '', 'files' => true]) !!}
{{ csrf_field() }}
<div class="form-group">
<label class="control-label" for="title">Title:</label>
<input type="text" name="title" class="form-control" data-error="Please enter title." required />
<div class="help-block with-errors"></div>
</div>
<div class="form-group">
<label class="control-label" for="title">Slug:</label>
<input type="text" name="slug" class="form-control" data-error="Please enter title." required />
<div class="help-block with-errors"></div>
</div>
{{ Form::label('category_id', 'Category') }}
<select id="add-category" class="form-control" name="category_id">
#foreach($categories as $category)
<option value='{{ $category->id }}'>{{ $category->name }}</option>
#endforeach
</select>
{{ Form::label('featured_image', 'Upload Featured Image:', ['class' => 'form-spacing-top']) }}
{{ Form::file('featured_image',["id" => 'add-image', "class" => 'form-control-file']) }}
{{ Form::label('body', 'Post Body:') }}
{{ Form::textarea('body', null, array('id' => 'add-body', 'class' => 'form-control')) }}
{{ Form::button('Create Post', array('id' => 'submit-post', 'class' => 'btn btn-success btn-lg btn-block', 'style' => 'margin-top: 20px;'))}}
{!! Form::close() !!}
</div>
</div>
Ajax Code:
$(document).on('click', '.create-post', function() {
$('.create-form').css('display','block');
$('.posts-table').css('display','none');
});
$('#submit-post').click(function(e) {
e.preventDefault();
var action = $('#form-post').attr('route');
var title = $("#form-post").find("input[name='title']").val();
var slug = $("#form-post").find("input[name='slug']").val();
var category_id = $("#add-category").val();
var featured_image = $("#add-image").val();
var body = $("#add-body").val();
$.ajax({
type : 'POST',
url : "/addpost",
headers: {
'X-CSRF-TOKEN' : $('input[name="_token"]').val()
},
data : {
title: title,
slug: slug,
category_id: category_id,
featured_image: featured_image,
body: body
},
success: function(data){
$('.create-form').css('display','none');
$('.posts-table').css('display','block');
$('.table tbody').append("<tr id='" + data.id + "' class='item'><th>" + data.id + "</th><td>" + data.title + "</td><td>" + data.body + "</td><td>date</td><td><button class='show-modal btn btn-success' data-id='" + data.id + "' data-title='" + data.title + "' data-slug='" + data.slug + "' data-category='" + data.category_id + "' data-image='" + data.featured_image + "' data-body='" + data.body + "'><span class='glyphicon glyphicon-eye-open'></span> Show</button><button class='edit-modal btn btn-info' data-id='" + data.id + "' data-title='" + data.title + "' data-slug='" + data.slug + "' data-category='" + data.category_id + "' data-image='" + data.featured_image + "' data-body='" + data.body + "'><span class='glyphicon glyphicon-edit'></span> Edit</button><button class='delete-modal btn btn-danger' data-id='" + data.id + "' data-title='" + data.title + "' data-slug='" + data.slug + "' data-category='" + data.category_id + "' data-image='" + data.featured_image + "' data-body='" + data.body + "'><span class='glyphicon glyphicon-trash'></span> Delete</button></td></tr>");
console.log(data);
}
});
});
It's not enough information about the error.
Try dd() in your controller & check it in [F12 -> Network].
And since you're using ajax to sending request, there no need to define options (action, route) in Form. remove it.
I'm trying to create an Editor Template for a ViewModel and I see that Kendo controls are facing issues after being generated.
Here is the ParkingServiceDetail.cshtml file:
#model List<DA.Services.CarPark.Presentation.Web.Models.ParkingServiceDetailViewModel>
<div id="#ViewData.TemplateInfo.HtmlFieldPrefix" style="margin-top:10px">
<table class="table table-bordered table-striped table-hover" id="grid">
<thead>
<tr>
<th data-field="TerminalId">Terminal</th>
<th data-field="ServiceId">Service</th>
<th data-field="ParkingCardNumber">Card Number</th>
<th data-field="ParkingCardIssueDate">Issue Date</th>
<th data-field="ParkingCardExpiryDate">Expiry Date</th>
<th data-field="ParkingCardGroup">Card Group</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#if (Model != null && Model.Any())
{
for (int i = 0; i < Model.Count; i++)
{
<tr mjrole="#(Model[i].ParkingCardNumber == "viewtemplate" ? "template" : "row")" style="display:#(Model[i].ParkingCardNumber == "viewtemplate" ? "none" : "")">
<td>#Html.DropDownListFor(m => m[i].TerminalId, (IEnumerable<SelectListItem>)ViewBag.Terminals, "Select terminal", new { #class = "form-control", style = "width:150px", mjrole = ViewData.TemplateInfo.HtmlFieldPrefix + "-terminal" })</td>
<td>#Html.DropDownListFor(m => m[i].ServiceId, (IEnumerable<SelectListItem>)ViewBag.Services, "Select service", new { #class = "form-control", style = "width:150px", mjrole = ViewData.TemplateInfo.HtmlFieldPrefix + "-service" })</td>
<td>#Html.TextBoxFor(m => m[i].ParkingCardNumber, new { #class = "k-textbox form-control" })</td>
<td>#Html.TextBoxFor(m => m[i].ParkingCardIssueDate, new { #class = "form-control", style = "width:115px", mjrole = "dateIs" })</td>
<td>#Html.TextBoxFor(m => m[i].ParkingCardExpiryDate, new { #class = "form-control", style = "width:115px", mjrole = "dateEx" })</td>
<td>#Html.TextBoxFor(m => m[i].ParkingCardGroup, new { #class = "k-textbox form-control", style = "width:100px" })</td>
<td>
<button command="#ViewData.TemplateInfo.HtmlFieldPrefix-delete" id="DeptFlightSearch" type="button" class="btn btn-danger #(Model[i].TerminalId > 0 ? "disabled" : "")">
<span class="glyphicon glyphicon-remove-circle"></span>
Delete
</button>
</td>
<script type="text/javascript">
var tempParent = $("select[mjrole='#ViewData.TemplateInfo.HtmlFieldPrefix-terminal']")
.kendoDropDownList({
optionLabel: "Select terminal...",
dataTextField: "TerminalName",
dataValueField: "TerminalId",
dataSource: {
serverFiltering: true,
transport: {
read: {
url: "Ajax/GetTerminals",
dataType: "json"
}
}
}
});
$("select[mjrole='#ViewData.TemplateInfo.HtmlFieldPrefix-service']")
.kendoDropDownList({
autoBind: false,
cascadeFrom: tempParent.id,
optionLabel: "Select service...",
dataTextField: "NameEnglish",
dataValueField: "Code",
dataSource: {
serverFiltering: true,
transport: {
read: {
url: "Ajax/GetTerminalServices",
data: "filterServices",
dataType: "json"
}
}
}
});
</script>
</tr>
}
}
<tr id="#ViewData.TemplateInfo.HtmlFieldPrefix-empty" style="display: #(Model != null && Model[0].ParkingCardNumber == "viewtemplate" && Model.Count > 1 ? "none": "")">
<td colspan="7">
No services added
</td>
</tr>
<tr mjrole="footer">
<td colspan="7" style="text-align: right;">
<button id="#ViewData.TemplateInfo.HtmlFieldPrefix-AddNew" type="button" class="btn btn-outline btn-success btn-circle btn-lg">
<span class="fa fa-plus"></span>
</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal fade" id="#ViewData.TemplateInfo.HtmlFieldPrefix-popup" tabindex="-1" role="dialog">
<div class="modal-dialog" role="dialog" style="width:700px">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h3 class="modal-title" id="myModalLabel">Confirmation</h3>
</div>
<div class="modal-body">
<h5> Are you sure you want to delete the selected service? </h5>
<table class="table table-bordered table-striped" id="deletegrid"></table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline btn-danger btn-circle btn-lg" data-dismiss="modal">
<span class="glyphicon glyphicon-remove"></span>
</button>
<button id="#ViewData.TemplateInfo.HtmlFieldPrefix-ok" type="button" class="btn btn-outline btn-success btn-circle btn-lg">
<span class="glyphicon glyphicon-ok"></span>
</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$("##ViewData.TemplateInfo.HtmlFieldPrefix").on("click", "button[command='#ViewData.TemplateInfo.HtmlFieldPrefix-delete']", function (arg) {
var row = $(arg.target).parent().closest("tr");
$('##ViewData.TemplateInfo.HtmlFieldPrefix').prop("target", row);
$('##ViewData.TemplateInfo.HtmlFieldPrefix-popup').modal('show');
});
$("##ViewData.TemplateInfo.HtmlFieldPrefix-ok").click(function () {
var row = $('##ViewData.TemplateInfo.HtmlFieldPrefix').prop("target");
row.remove();
$("##ViewData.TemplateInfo.HtmlFieldPrefix").find("tr[mjrole='row']").each(function (index) {
var tempControl;
tempControl = $(this).find("[id$='TerminalId']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__TerminalId");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].TerminalId");
tempControl = $(this).find("[id$='ServiceId']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ServiceId");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ServiceId");
tempControl = $(this).find("[id$='ParkingCardNumber']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardNumber");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardNumber");
tempControl = $(this).find("[id$='ParkingCardIssueDate']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardIssueDate");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardIssueDate");
tempControl = $(this).find("[id$='ParkingCardExpiryDate']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardExpiryDate");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardExpiryDate");
tempControl = $(this).find("[id$='ParkingCardGroup']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardGroup");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardGroup");
});
$('##ViewData.TemplateInfo.HtmlFieldPrefix-popup').modal('hide');
if ($("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='row']").length > 0) {
$("##ViewData.TemplateInfo.HtmlFieldPrefix-empty").hide();
}
else {
$("##ViewData.TemplateInfo.HtmlFieldPrefix-empty").show();
}
});
$("##ViewData.TemplateInfo.HtmlFieldPrefix-AddNew").click(function () {
var row;
if ($("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='template']").length > 0) {
row = $("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='template']").clone();
}
else {
row = $("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='row']").first().clone();
}
row.attr("mjrole", "row").show();
row.find("input[name$='ParkingCardNumber']").val("");
row.insertAfter($("##ViewData.TemplateInfo.HtmlFieldPrefix table tr").not($("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='footer']")).last());
if ($("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='row']").length > 0) {
$("##ViewData.TemplateInfo.HtmlFieldPrefix-empty").hide();
}
else {
$("##ViewData.TemplateInfo.HtmlFieldPrefix-empty").show();
}
$("##ViewData.TemplateInfo.HtmlFieldPrefix").find("tr[mjrole='row']").each(function (index) {
var tempControl;
tempControl = $(this).find("[id$='TerminalId']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__TerminalId");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].TerminalId");
tempControl = $(this).find("[id$='ServiceId']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ServiceId");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ServiceId");
tempControl = $(this).find("[id$='ParkingCardNumber']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardNumber");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardNumber");
tempControl = $(this).find("[id$='ParkingCardIssueDate']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardIssueDate");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardIssueDate");
tempControl = $(this).find("[id$='ParkingCardExpiryDate']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardExpiryDate");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardExpiryDate");
tempControl = $(this).find("[id$='ParkingCardGroup']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardGroup");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardGroup");
});
$("input[mjrole='dateIs']").kendoDatePicker({ culture: "ar-AE" });
$("input[mjrole='dateEx']").kendoDatePicker({ culture: "ar-AE" });
});
function filterServices() {
return {
companyId: '#ViewData["CompanyId"]',
terminalId: $("#TerminalId").val()
};
}
</script>
It seem intimidating but only because of list ordering workaround. This is pretty basic stuff.
I was originally using the Html.Helpers controls and they work OK. However, I need to manage a few cascading drop-downs in each row. And that's why you see the script tag right after the generation.
Issue is that the widget initiation was failing for all Kendo controls. I solved the DatePicker by initiating them after the Add Button code in JS. But they are not really dependent so that was easy. I cannot do the same for the two drop-downs though.
Currently, at runtime, the two drop-downs get converted to Kendo and are in a sort of disabled state and do not accept any inputs or respond to any attribute changes through browser debuggers.
And I have confirmed that if I move the bit of JS from tr generation to after Add button click, it works but I lose ids that I need create cascading dependencies.
Is there some threading timing issues here that fail in case of Kendo but not the regular controls?
Update
Main issue I identified was the names of the Kendo controls were not unique. New code in my answer below. This resolves 50% of the question.
I was able to solve the blocked out kendo controls by naming them properly. Now for the existing records (if I send a few in the List<>), the rows render correctly with proper kendo controls. However, for new inserted rows, the same issue comes back as I have yet to figure out how to rename in that scenario.
Also, the cascading combos are not working either.
Here is the working code:
#model List<DA.Services.CarPark.Presentation.Web.Models.ParkingServiceDetailViewModel>
<div id="#ViewData.TemplateInfo.HtmlFieldPrefix" style="margin-top:10px">
<table class="table table-bordered table-striped table-hover" id="grid">
<thead>
<tr>
<th data-field="TerminalId">Terminal</th>
<th data-field="ServiceId">Service</th>
<th data-field="ParkingCardNumber">Card Number</th>
<th data-field="ParkingCardIssueDate">Issue Date</th>
<th data-field="ParkingCardExpiryDate">Expiry Date</th>
<th data-field="ParkingCardGroup">Card Group</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#if (Model != null && Model.Any())
{
for (var i = 0; i < Model.Count; i++)
{
<tr mjrole="#(Model[i].ParkingCardNumber == "viewtemplate" ? "template" : "row")" style="display: #(Model[i].ParkingCardNumber == "viewtemplate" ? "none" : "")">
<td>#(Html.Kendo().DropDownListFor(m => m[i].TerminalId)
.Name(ViewData.TemplateInfo.HtmlFieldPrefix + "[" + (i + 1) + "].TerminalId")
.OptionLabel("Select terminal...")
.DataTextField("TerminalName")
.DataValueField("TerminalId")
.DataSource(source => source
.Read(read => read
.Action("GetTerminals", "Ajax")
.Type(HttpVerbs.Post)
)
)
.HtmlAttributes(new {
#class = "form-control", style = "width:150px",
mjrole = ViewData.TemplateInfo.HtmlFieldPrefix + "-terminal"
})
)
</td>
<td>#(Html.Kendo().DropDownListFor(m => m[i].ServiceId)
.Name(ViewData.TemplateInfo.HtmlFieldPrefix + "[" + (i + 1) + "].ServiceId")
.OptionLabel("Select service...")
.DataTextField("NameEnglish")
.DataValueField("Code")
.AutoBind(false)
.CascadeFrom(ViewData.TemplateInfo.HtmlFieldPrefix + "_" + (i + 1) + "__TerminalId")
.DataSource(source => source
.Read(read => read
.Action("GetTerminalServices", "Ajax")
.Type(HttpVerbs.Post)
)
)
.HtmlAttributes(new {
#class = "form-control", style = "width:150px",
mjrole = ViewData.TemplateInfo.HtmlFieldPrefix + "-service"
})
)
</td>
<td>#(Html.Kendo().TextBoxFor( m => m[i].ParkingCardNumber) .Name(ViewData.TemplateInfo.HtmlFieldPrefix + "[" + (i + 1) + "].ParkingCardNumber") .HtmlAttributes(new { #class = "form-control" }))</td>
<td>#(Html.Kendo().DatePickerFor(m => m[i].ParkingCardIssueDate) .Name(ViewData.TemplateInfo.HtmlFieldPrefix + "[" + (i + 1) + "].ParkingCardIssueDate") .Culture("ar-AE").HtmlAttributes(new { #class = "form-control", style = "width:115px", mjrole = "dateIs" }))</td>
<td>#(Html.Kendo().DatePickerFor(m => m[i].ParkingCardExpiryDate).Name(ViewData.TemplateInfo.HtmlFieldPrefix + "[" + (i + 1) + "].ParkingCardExpiryDate").Culture("ar-AE").HtmlAttributes(new { #class = "form-control", style = "width:115px", mjrole = "dateEx" }))</td>
<td>#(Html.Kendo().TextBoxFor( m => m[i].ParkingCardGroup) .Name(ViewData.TemplateInfo.HtmlFieldPrefix + "[" + (i + 1) + "].ParkingCardGroup") .HtmlAttributes(new { #class = "form-control", style = "width: 100px" }))</td>
<td>
<button command="#ViewData.TemplateInfo.HtmlFieldPrefix-delete" id="DeptFlightSearch" type="button" class="btn btn-danger #(Model[i].TerminalId > 0 ? "disabled" : "")">
<span class="glyphicon glyphicon-remove-circle"></span>
Delete
</button>
</td>
<script>
var tempDropdown = $('##ViewData.TemplateInfo.HtmlFieldPrefix' + '_#(i + 1)__TerminalId').data("kendoDropDownList");
$("#" + #ViewData.TemplateInfo.HtmlFieldPrefix + "_" + (i + 1) + "__ServiceId").data("kendoDropDownList").dataSource().read().transport().data(function(){return {companyId : #ViewBag.CompanyId, terminalId : tempDropdown.value() }} );
</script>
</tr>
}
}
<tr id="#ViewData.TemplateInfo.HtmlFieldPrefix-empty" style="display: #(Model != null && Model[0].ParkingCardNumber == "viewtemplate" && Model.Count > 1 ? "none": "")">
<td colspan="7">
No services added
</td>
</tr>
<tr mjrole="footer">
<td colspan="7" style="text-align: right;">
<button id="#ViewData.TemplateInfo.HtmlFieldPrefix-AddNew" type="button" class="btn btn-outline btn-success btn-circle btn-lg">
<span class="fa fa-plus"></span>
</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal fade" id="#ViewData.TemplateInfo.HtmlFieldPrefix-popup" tabindex="-1" role="dialog">
<div class="modal-dialog" role="dialog" style="width:700px">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h3 class="modal-title" id="myModalLabel">Confirmation</h3>
</div>
<div class="modal-body">
<h5> Are you sure you want to delete the selected service? </h5>
<table class="table table-bordered table-striped" id="deletegrid"></table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline btn-danger btn-circle btn-lg" data-dismiss="modal">
<span class="glyphicon glyphicon-remove"></span>
</button>
<button id="#ViewData.TemplateInfo.HtmlFieldPrefix-ok" type="button" class="btn btn-outline btn-success btn-circle btn-lg">
<span class="glyphicon glyphicon-ok"></span>
</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$("##ViewData.TemplateInfo.HtmlFieldPrefix").on("click", "button[command='#ViewData.TemplateInfo.HtmlFieldPrefix-delete']", function (arg) {
var row = $(arg.target).parent().closest("tr");
$('##ViewData.TemplateInfo.HtmlFieldPrefix').prop("target", row);
$('##ViewData.TemplateInfo.HtmlFieldPrefix-popup').modal('show');
});
$("##ViewData.TemplateInfo.HtmlFieldPrefix-ok").click(function () {
var row = $('##ViewData.TemplateInfo.HtmlFieldPrefix').prop("target");
row.remove();
$("##ViewData.TemplateInfo.HtmlFieldPrefix").find("tr[mjrole='row']").each(function (index) {
var tempControl;
tempControl = $(this).find("[id$='TerminalId']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__TerminalId");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].TerminalId");
tempControl = $(this).find("[id$='ServiceId']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ServiceId");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ServiceId");
tempControl = $(this).find("[id$='ParkingCardNumber']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardNumber");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardNumber");
tempControl = $(this).find("[id$='ParkingCardIssueDate']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardIssueDate");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardIssueDate");
tempControl = $(this).find("[id$='ParkingCardExpiryDate']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardExpiryDate");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardExpiryDate");
tempControl = $(this).find("[id$='ParkingCardGroup']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardGroup");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardGroup");
});
$('##ViewData.TemplateInfo.HtmlFieldPrefix-popup').modal('hide');
if ($("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='row']").length > 0) {
$("##ViewData.TemplateInfo.HtmlFieldPrefix-empty").hide();
}
else {
$("##ViewData.TemplateInfo.HtmlFieldPrefix-empty").show();
}
});
$("##ViewData.TemplateInfo.HtmlFieldPrefix-AddNew").click(function () {
var row;
if ($("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='template']").length > 0) {
row = $("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='template']").clone();
}
else {
row = $("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='row']").first().clone();
}
row.attr("mjrole", "row").show();
row.find("input[name$='ParkingCardNumber']").val("");
row.insertAfter($("##ViewData.TemplateInfo.HtmlFieldPrefix table tr").not($("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='footer']")).last());
if ($("##ViewData.TemplateInfo.HtmlFieldPrefix table tr[mjrole='row']").length > 0) {
$("##ViewData.TemplateInfo.HtmlFieldPrefix-empty").hide();
}
else {
$("##ViewData.TemplateInfo.HtmlFieldPrefix-empty").show();
}
$("##ViewData.TemplateInfo.HtmlFieldPrefix").find("tr[mjrole='row']").each(function (index) {
var tempControl;
tempControl = $(this).find("[id$='TerminalId']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__TerminalId");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].TerminalId");
tempControl = $(this).find("[id$='ServiceId']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ServiceId");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ServiceId");
tempControl = $(this).find("[id$='ParkingCardNumber']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardNumber");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardNumber");
tempControl = $(this).find("[id$='ParkingCardIssueDate']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardIssueDate");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardIssueDate");
tempControl = $(this).find("[id$='ParkingCardExpiryDate']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardExpiryDate");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardExpiryDate");
tempControl = $(this).find("[id$='ParkingCardGroup']");
tempControl.attr("id", "#(ViewData.TemplateInfo.HtmlFieldPrefix)_" + (index + 1) + "__ParkingCardGroup");
tempControl.attr("name", "#(ViewData.TemplateInfo.HtmlFieldPrefix)[" + (index + 1) + "].ParkingCardGroup");
});
});
function filterServices() {
return {
companyId: '#ViewData["CompanyId"]',
terminalId: $("#TerminalId").val()
};
}
</script>
I'm using Ajax for CRUD. How can I use an associative array for inserting data with Ajax, so I don't have to reload the page and to append the inserted data below the existing data?
Here's The JS
function addTextBox(section, id_group) {
row_section = "#row_" + section;
wrapper = $(row_section);
// $(wrapper).append('<div class="movement_group"><input type="text" class="title_group" name="title_detail[' + section + ']" placeholder="Input" required="" style="width: 300px" /><button type="button" style="margin-left:10px;" class="btn btn-sm sending">Ok</button><button type="button" onClick="remove_field(\'' + section + '\')" style="margin-left:10px;" class="btn btn-sm remove_content">X</button></div>'); //add input box
// $(wrapper).append('<ul id="' + section + '" class="input_fields" style="list-style-type:none"><li><div class="movement_group"><input type="text" class="title_group" name="title_detail[\'' + section + '\']" placeholder="Input" required="" style="width: 300px" /><button type="button" style="margin-left:10px;" class="btn btn-sm sending">Ok</button><button type="button" onClick="remove_field(\'' + section + '\')" style="margin-left:10px;" class="btn btn-sm remove_content">X</button></div></li></ul>'); //add input box
$(wrapper).append('<ul id="fail_' + section + '" class="input_fields" style="list-style-type:none"><li><div class="movement_group"><input type="text" id="txt_' + section + '" id_group = "' + id_group + '"class="title_group" name="title_detail[\'' + section + '\']" placeholder="Input" required="" style="width: 300px" /><button type="button" style="margin-left:10px;" class="btn btn-sm sending" onClick="saveTitleGroup(\'' + section + '\', \'' + id_group + '\')">Ok</button><button type="button" onClick="remove_field(\'' + section + '\')" style="margin-left:10px;" class="btn btn-sm remove_content">X</button></div></li></ul>'); //add input box }
function remove_field(section) {
section_id = "#fail_" + section;
$(section_id).remove(); }
function saveTitleGroup(section, id_group) {
title_group = "#txt_" + section;
title_group = $(title_group).val();
td_section = "#td_" + section;
row_section = "#row_section" + section;
$.ajax({
type: "POST",
url: adminUrl+"/interest/save_detail",
data: {title: title_group, interest_group_id: id_group},
dataType: "text",
cache:false,
success:
function(data, textStatus, jqXHR){
console.log('test');
console.log(row_section);
/*$('.movement').fadeOut(800, function(){
$('.movement').fadeIn().delay(500);
// $('.movement').reload('http://127.0.0.1/camtravel-web/administrator/interest');
// return data;
window.location.reload();
});*/
// console.log(row_section);
// console.log(title_group);
// $('#tableinterest').html('');
$(td_section).html(data);
// $(row_section).html(''');
}
}); }
View
<table id="tableinterest" class="table table-bordered table-striped">
<thead>
<tr>
<th>No</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<?php
$n=0;
foreach ($interest_groups as $interest_group) {
$n++;
echo "<tr>";
echo "<td>";
// echo $interest_group['id'] . ". "
echo $n . ". ";
?>
</td>
<?php
echo "<td id='td_section_$interest_group[id]' group-id='$interest_group[id]'>";
// echo "<div id='title_group_'></div>";
echo "<b style='font-size:11pt !important;'>" . $interest_group['title'] . "</b>" . "<span style='margin-left:850px; font-size:15pt;' class='glyphicon glyphicon-plus interest_add' data-toggle='tooltip' data-placement='top' title='Add Detail' onclick='addTextBox(\"section_$interest_group[id]\", \"$interest_group[id]\")'></span><button type='button' style='float:right;' class='btn btn-xs text-red btn-delete-group' data-id='$interest_group[id]' data-category='$interest_group[title]'><span class='glyphicon glyphicon-minus'></span></button> ";
echo "<br>";
echo "</br>";
foreach ($interest_details as $interest_detail) {
echo "<ul style='list-style-type:none'>";
if ($interest_detail['interest_group_id'] == $interest_group['id']) {
echo "<li id='" . $interest_detail['id'] . "'>" . "<label style='font-size:10pt !important;' data-title=\"$interest_detail[title]\" id=\"$interest_detail[id]\" detail_id=\"$interest_group[id]\" class='editme1' id-title='\"$interest_group[id]\"'>" . $interest_detail['title'] . "</label>" .
"<button type='button' style='float:right;' class='btn btn-xs btn-delete-interest text-red' data-id='$interest_detail[id]' data-category='$interest_detail[title]'><span class='glyphicon glyphicon-minus'></span></button>" . "</li>";
}
echo "</ul>";
}
/*echo "<ul style='list-style-type:none'>";
echo "<li id='row_section_$interest_group[id]' class='input_fields'>" . "</li>";
echo "</ul>";*/
echo "<div id='row_section_$interest_group[id]'></div>";
echo "</td>";
// echo "<tr class='input_content'>";
// echo "</tr>";
echo "</tr>";
}
?>
</tbody>
</table>
Controller
function save_detail(){
// $id = $this->input->post('interest_group_id');
$title = $this->input->post('title');
$save = $this->save = $this->interest_group->save();
if ($save) {
echo $title;
// redirect('administrator/interest','refresh');
$this->layout = false;
} else {
echo "save failed";
// $this->layout = false;
}
// $title = $this->input->post('id-title');
// echo $title;
}
Model
function save(){
$id = $this->input->post('id');
// date_default_timezone_set('Asia/Jakarta');
$data = array(
"interest_group_id" => $this->input->post('interest_group_id'),
"title" => $this->input->post('title'),
"created_at" => date("Y-m-d H:i:s"),
"updated_at" => date("Y-m-d H:i:s"),
);
if ($id == null) {
$save = $this->db->insert('interest_detail',$data);
if ($save) {
return true;
$data = array();
$data['interest_group_id'] = 'interest_group_id';
$data['title'] = 'title';
// $data['title'] =
$data = array("data" => $data);
$data = json_encode($data);
$interest_group = $this->get_interest_group_by_id($this->input->post('interest_group_id'));
$interest_details = $this->get_interest_detail_by_id($this->input->post('interest_group_id'));
echo "<b>" . $interest_group['title'] . "</b>" . "<span style='margin-left:875px;' class='glyphicon glyphicon-plus interest_add' data-toggle='tooltip' data-placement='top' title='Add Detail' onclick='addTextBox(\"section_$interest_group[id]\", \"$interest_group[id]\")'></span><button type='button' style='float:right;' class='btn btn-xs text-red btn-delete-group' data-id='$interest_group[id]' data-category='$interest_group[title]'><span class='glyphicon glyphicon-minus'></span></button> ";
echo "<br>";
echo "<br>";
foreach ($interest_details as $interest_detail) {
echo "<ul style='list-style-type:none'>";
if ($interest_detail['interest_group_id'] == $interest_group['id']) {
echo "<li>" . "<label class='editme1'>" . $interest_detail['title'] . "</label>" .
"<button type='button' style='float:right;' class='btn btn-xs btn-delete-interest text-red' data-id='$interest_detail[id]' data-category='$interest_detail[title]'><span class='glyphicon glyphicon-minus'></span></button>" . "</li>";
}
echo "</ul>";
}
echo "<div id='row_section_$interest_group[id]'></div>";
print_r($interest_group);
print_r($interest_details);
} else {
return false;
}
} else {
$this->db->where('id', $id);
$update = $this->db->update('interest_detail', $data);
if ($update) {
return true;
} else {
return false;
}
}
}
Use single quotes when defining a string $string = '<div class"dre"></div>' and associative arrays need quotes names $array['name'] not $array[name] and last properly concatenate the strings and variables.
Try this:
<table id="tableinterest" class="table table-bordered table-striped">
<thead>
<tr>
<th>No</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<?php
$n=0;
foreach ($interest_groups as $interest_group) {
$n++;
echo "<tr>";
echo "<td>";
// echo $interest_group['id'] . ". "
echo $n . ". ";
?>
</td>
<?php
echo "<td id='td_section_".$interest_group['id']."' group-id='".$interest_group['id']."'>";
echo "<b style='font-size:11pt !important;'>" . $interest_group['title'] . "</b>" . '<span style="margin-left:850px; font-size:15pt;" class="glyphicon glyphicon-plus interest_add" data-toggle="tooltip" data-placement="top" title="Add Detail" onclick="addTextBox(section_'.$interest_group['id'].','.$interest_group['id'].')"></span><button type="button" style="float:right;" class="btn btn-xs text-red btn-delete-group" data-id='.$interest_group['id'].' data-category="'.$interest_group['title'].'"><span class="glyphicon glyphicon-minus"></span></button> ';
echo "<br>";
echo "</br>";
foreach ($interest_details as $interest_detail) {
echo "<ul style='list-style-type:none'>";
if ($interest_detail['interest_group_id'] == $interest_group['id']) {
echo "<li id='" . $interest_detail['id'] . "'>" . "<label style='font-size:10pt !important;' data-title=\"".$interest_detail['title']."\" id=\"".$interest_detail['id']."\" detail_id=\"".$interest_group['id']."\" class='editme1' id-title='\"".$interest_group['id']."\"'>" . $interest_detail['title'] . "</label>" .
"<button type='button' style='float:right;' class='btn btn-xs btn-delete-interest text-red' data-id='$interest_detail[id]' data-category='$interest_detail[title]'><span class='glyphicon glyphicon-minus'></span></button>" . "</li>";
}
echo "</ul>";
}
echo "<div id='row_section_".$interest_group['id']."'></div>";
echo "</td>"
echo "</tr>";
}
?>
</tbody>
</table>