I have initialised Summernot editor in my Laravel 9 app but it doesn't seem to send the data from summernote editor. I'm sending form data using ajax. It returns validation error as 'required' since the summernote data is required. When i check the console i see the 'data required' response and in the request tab you see that no data is being captured by the summernote editor despite typing in some data.
Find below my code implementation
@extends('backend.layout.general')
@section('title', 'Add Nutrition Item')
@section('styles')
<!-- Dropify -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Dropify/0.2.2/css/dropify.min.css" integrity="sha512-EZSUkJWTjzDlspOoPSpUFR0o0Xy7jdzW//6qhUkoZ9c4StFkVsp9fbbd0O06p9ELS3H486m4wmrCELjza4JEog==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="{{ asset('backend/plugins/summernote/summernote-bs4.min.css') }}">
@endsection
@section('scripts')
<!--Internal Sweet-Alert js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/sweetalert2.all.min.js"></script>
<!-- custom js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.min.js"></script>
<!-- Dropify -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Dropify/0.2.2/js/dropify.min.js" integrity="sha512-8QFTrG0oeOiyWo/VM9Y8kgxdlCryqhIxVeRpWSezdRRAvarxVtwLnGroJgnVW9/XBRduxO/z1GblzPrMQoeuew==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>}
<script src="{{ asset('backend/plugins/summernote/summernote-bs4.min.js') }}"></script>
<script>
$('.dropify').dropify();
// Summernote
$('#description').summernote({
height: 200,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link']],
['view', ['help']]
]
});
$('#ingredients').summernote({
height: 200,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link']],
['view', ['help']]
]
});
$('#directions').summernote({
height: 200,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link']],
['view', ['help']]
]
});
if($("#createNutritionForm").length > 0) {
$("#createNutritionForm").validate({
rules: {
title: {
required: true,
},
image: {
required: true,
}
},
message: {
title: {
required: "Please Enter Nutrition Title",
},
image: {
required: true,
}
},
submitHandler: function(form) {
let myForm = document.getElementById('createNutritionForm');
let formData = new FormData(myForm);
$("#createNutritionBtn").text('Please wait .....');
$("#createNutritionBtn").attr("disabled", true);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: "{{ route('nutritions.store') }}",
type: "POST",
data: formData,
dataType: 'JSON',
contentType: false,
processData: false,
success: function(response) {
if(response.success) {
Swal.fire({
position: 'top-end',
icon: 'success',
title: response.msg,
timer: 1500
}).then(function() {
window.location = "{{ route('nutritions.index') }}"
});
} else {
Swal.fire({
position: 'top-end',
icon: 'error',
title: response.msg,
timer: 1500
}).then(function() {
window.location = "{{ route('nutritions.index') }}"
});
}
},
error: function(error) {
console.log(error);
},
complete: function() {
document.getElementById("createNutritionForm").reset();
$("#createNutritionBtn").text('Create Body Part');
$("#createNutritionBtn").attr("disabled", false);
}
});
}
});
}
</script>
@endsection
@section('content')
<div >
<section >
<div >
<div >
<div >
<h1>Nutrition Items Management</h1>
</div>
<div >
<ol >
<li ><a href="{{ route('nutritions.index') }}">Nutrition Items</a></li>
<li >Add Nutrition Item</li>
</ol>
</div>
</div>
</div>
</section>
<section >
<div >
<div >
<div >
<div >
<div >
<h3 >Add Nutrition Item</h3>
</div>
<form id="createNutritionForm" method="POST" action="javascript:void(0)" novalidate="novalidate" enctype="multipart/form-data">
<div >
<div >
<label for="title">Title</label>
<input type="text" id="title" name="title"
placeholder="Enter Nutrition Item Title" required>
</div>
<div >
<label for="description">Description</label>
<textarea id="description" name="description"></textarea>
</div>
<div >
<label for="description">Ingredients</label>
<textarea id="ingredients" name="ingredients"></textarea>
</div>
<div >
<label for="description">Directions</label>
<textarea id="directions" name="directions"></textarea>
</div>
<div >
<div >
<div >
<label for="category_id">Category</label>
<select id="workout_intensity" name="workout_intensity" style="width: 100%;" required>
<option selected="selected">Select Category</option>
<option value="low">Low</option>
<option value="moderate">Moderate</option>
<option value="high">High</option>
</select>
</div>
</div>
<div >
<div >
<label for="calories">Calories</label>
<input type="text" id="calories" name="calories"
placeholder="Enter Calories" required>
</div>
</div>
</div>
<div >
<div >
<div >
<label for="carbs">Carbs</label>
<input type="text" id="carbs" name="carbs"
placeholder="Enter the Carbs" required>
</div>
</div>
<div >
<div >
<label for="protein">Protein</label>
<input type="text" id="protein" name="protein"
placeholder="Enter Protein" required>
</div>
</div>
</div>
<div >
<div >
<div >
<label for="fat">Fat</label>
<input type="text" id="fat" name="fat"
placeholder="Enter the Fat" required>
</div>
</div>
<div >
<div >
<label for="servings">Servings</label>
<input type="text" id="servings" name="servings"
placeholder="Enter the Servings" required>
</div>
</div>
</div>
<div >
<div >
<div >
<label for="total_time">Total Time</label>
<input type="text" id="total_time" name="total_time"
placeholder="Enter the Total Time" required>
</div>
</div>
<div >
<div >
<label for="image">Nutrition Item Image</label>
<input type="file" data-max-file-size="3M" accept=".jpeg, .jpg, .webp, .png" id="image" name="image" required>
</div>
</div>
</div>
<div >
<div >
<div >
<label for="featured">Featured</label><br/>
<div >
<input type="radio" id="featured-y" name="featured" value="true">
<label for="featured-y">Yes</label>
</div>
<div >
<input type="radio" id="featured-n" name="featured" value="false" checked>
<label for="featured-n">No</label>
</div>
</div>
</div>
<div >
<div >
<label for="status">Status</label><br/>
<div >
<input type="radio" id="published" name="status" value="published" >
<label for="published">Published</label>
</div>
<div >
<input type="radio" id="draft" name="status" value="draft" checked>
<label for="draft">Draft</label>
</div>
</div>
</div>
</div>
</div>
<div >
<button type="submit" id="createNutritionBtn" >Add Nutrition Item</button>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
</div>
@endsection
Controller
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required',
'description' => 'required',
'ingredients' => 'required',
'directions' => 'required',
'category_id' => 'required',
'calories' => 'required',
'carbs' => 'required',
'protein' => 'required',
'fat' => 'required',
'servings' => 'required',
'total_time' => 'required',
'featured' => 'required',
'status' => 'required'
]);
if($request->hasFile('image')) {
// Upload an image file to cloudinary with one line of code
$image = Cloudinary::upload($request->file('image')->getRealPath())->getSecurePath();
$nutrition = Nutrition::create([
'title' => $request->title,
'description' => $request->description,
'ingredients' => $request->ingredients,
'directions' => $request->directions,
'category_id' => $request->category_id,
'calories' => $request->calories,
'carbs' => $request->carbs,
'protein' => $request->protein,
'fat' => $request->fat,
'servings' => $request->servings,
'total_time' => $request->total_time,
'featured' => $request->featured,
'status' => $request->status,
'image' => $image
]);
}
if($nutrition) {
return response()->json([
'success' => true,
'msg' => 'Nutrition Item added successfully!'
]);
} else {
return response()->json([
'success' => false,
'msg' => 'Something went wrong!'
]);
}
}
CodePudding user response:
Summernote is not a textarea and doesn't inject textarea value by default. to get data from summernote you can use callback.
$('#description').summernote({
callbacks: {
onChange: function(contents, $editable) {
console.log('onChange:', contents, $editable);
$('#descriptionInput').val(contents)
}
}
});
and the HTML tag should be like below:
<div >
<label for="description">Description</label>
<div id="description" ></div>
<input id="descriptionInput" type="hidden" name="description"></input>
</div>
Another way is use put form input manually using code()
method like this
CodePudding user response:
So i've been able to fix this issue by replacing the content of the formData.
formData.set('name', 'value');