How to create ajax functions to control a form - javascript

I am developing a form in laravel that shows products and projects of a certain department. I need to create a function in js/ajax so I can allow users to choose a product, and once that happens, the project field in the form should show a drop-down menu of all the projects related to that product. How can I do that? Below is the code for the form, which has two fields (Produto) and (Projeto).
<form action="/arquiteturas/store" method="post" role="form" class="form-horizontal">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group {{$errors->has('combo_produto')? ' has-error' : '' }}">
<label class="col-md-2 control-label">Product</label>
<div class="col-md-8">
<select class="form-control search-select" name="combo_produto"
id="combo_produto">
<option value="0">Choose</option>
#foreach($produtos as $value)
<option #if(old('combo_produto')==$value->id){{'selected'}}#endif value='{{$value->id}}'>{{$value->nome}}</option>
#endforeach
</select>
<span class="help-block">
#if($errors->has('combo_produto'))
#foreach ($errors->get('combo_produto') as $error)
<b>{{$error}}</b>
#endforeach
#endif
</span>
</div>
</div>
<!--Projet.-->
<div class="form-group {{$errors->has('combo_projeto')? ' has-error' : '' }}">
<label class="col-md-2 control-label">Project</label>
<div class="col-md-8">
<select class="form-control search-select" name="combo_projeto" id="combo_projeto">
<option value="0">Choose</option>
#foreach($produtos as $value)
<option #if(old('combo_projeto')==$value->id){{'selected'}}#endif value='{{$value->id}}'>{{$value->nome}}</option>
#endforeach
</select>
<span class="help-block">
#if($errors->has('combo_projeto'))
#foreach ($errors->get('combo_projeto') as $error)
<b>{{$error}}</b>
#endforeach
#endif
</span>
</div>
</div>
I am sharing an excerpt of code for a similar funcionality of a form in which the user selects a product from a dropdown menu. Once that happens, a list of related branches is shown in the branch dropdown menu.
loadProdutos()
$("#combo_produto" ).change(function() {
clearCampos('combo_branch')
if(checkItemSel('combo_produto')){
$('#div_produto').removeClass('has-error');
$('.help-produto').empty();
var produto_id = document.getElementById('combo_produto').value
$('#combo_branch').prop("disabled", false);
loadbranchs(produto_id )
}else{
insertCombo('combo_branch', '0','Selecione')
$('#combo_branch').prop("disabled", true);
}
});
$("#combo_branch" ).change(function() {
if(checkItemSel('combo_produto')){
$('#div_branch').removeClass('has-error');
$('.help-branch').empty();
}
});
function loadProdutos()
{
var request = $.ajax({
method:"GET",
url:"/validar_fontes/request_produtos",
dataType:"json",
beforeSend: function () {
blockPage();
},
complete: function() {
// unblock when remote call returns
$.unblockUI();
}
});
request.done(function(e){
if(e.status){
if(e.produtos.length>0)
{
$('#combo_produto').append('<option value="0">Selecione</option>');
$('#combo_produto').val("0").trigger("change");
for(var i=0;i<e.produtos.length;i++)
{
$('#combo_produto').append('<option value="'+e.produtos[i]['id']+'">'+e.produtos[i]['nome']+'</option>');
}
}else
{
$('#combo_produto').append('<option value="0">Nenhum produto encontrado</option>');
$('#combo_produto').val("0").trigger("change");
}
}
});
}
function loadbranchs(produto_id)
{
var request = $.ajax({
method:"GET",
url:"/validar_fontes/request_branchs",
data:{produto_id : produto_id},
dataType:"json",
beforeSend: function () {
blockPage();
},
complete: function() {
// unblock when remote call returns
$.unblockUI();
}
});
request.done(function(e){
if(e.status){
if(e.branchs.length>0)
{
$('#combo_branch').append('<option value="0">Selecione</option>');
$('#combo_branch').val("0").trigger("change");
for(var i=0;i<e.branchs.length;i++)
{
$('#combo_branch').append('<option value="'+e.branchs[i]['id']+'">'+e.branchs[i]['nome']+'</option>');
}
}else
{
$('#combo_branch').append('<option value="0">Nenhuma branch encontrada</option>');
$('#combo_branch').val("0").trigger("change");
}
}
});
}

You have to create a end point (server side method in laravel) which will take the "producto" and return all "projecto" related to selected "producto"
Then on change event of "producto" dropdown in javascript/jquery you need to call the avobe created method and pass the producto value.
The projecto list should be key value pair so that it can be populated in dropdown projecto
Here is a draft page what you are trying to achieve, let me know if you can understand by this.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="js/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type = "text/javascript">
function PopulateContinents() {
var producto = $('#combo_produto').val();
if (producto == "") {
alert("Please select a valid product");
}
else {
$('producto').empty().append('<option selected="selected" value="0">Loading...</option>');
$.ajax({
type: "POST",
url: pageUrl + '<enter the url of server method created>',
data: '{producto: ' + producto + '}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(datas){
for(i=0; i<datas.length; i++)
{
$('#combo_projeto options').append("<option value='"+datas[i].Value+"'>"+datas[i].Text+"</option>");
}
},
failure: function (response) {
alert(response.d);
}
});
}
}
</script>
<form action="/arquiteturas/store" method="post" role="form" class="form-horizontal">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group {{$errors->has('combo_produto')? ' has-error' : '' }}">
<label class="col-md-2 control-label">Product</label>
<div class="col-md-8">
<select class="form-control search-select" name="combo_produto"
id="combo_produto">
<option value="0">Choose</option>
#foreach($produtos as $value)
<option #if(old('combo_produto')==$value->id){{'selected'}}#endif value='{{$value->id}}'>{{$value->nome}}</option>
#endforeach
</select>
<span class="help-block">
#if($errors->has('combo_produto'))
#foreach ($errors->get('combo_produto') as $error)
<b>{{$error}}</b>
#endforeach
#endif
</span>
</div>
</div>
<!--Projet.-->
<div class="form-group {{$errors->has('combo_projeto')? ' has-error' : '' }}">
<label class="col-md-2 control-label">Project</label>
<div class="col-md-8">
<select class="form-control search-select" name="combo_projeto" id="combo_projeto">
<option value="0">Choose</option>
#foreach($produtos as $value)
<option #if(old('combo_projeto')==$value->id){{'selected'}}#endif value='{{$value->id}}'>{{$value->nome}}</option>
#endforeach
</select>
<span class="help-block">
#if($errors->has('combo_projeto'))
#foreach ($errors->get('combo_projeto') as $error)
<b>{{$error}}</b>
#endforeach
#endif
</span>
</div>
</div>
</body>
</html>

Related

Search by Name Category/SubCategory using Javascript on laravel view

I had some problems with the task. I'm not very good with javascript. Please help.
I display categories as form and I want to when the form to be typed to display products that are set for each category and sub-category. In the next task I have to make sure that when the form is typed, the categories show up and, also without refreshing the page.
code on product_upload.blade.view
<div class="form-group row" id="category">
<label class="col-md-3 col-from-label">{{translate('Category')}}</label>
<div class="col-md-8">
<select class="form-control aiz-selectpicker" name="category_id" id="category_id" data-live-search="true" required>
#foreach($categories as $category)
<option value="{{$category->id}}">{{ $category->getTranslation('name') }}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group row" id="subcategory">
<label class="col-md-3 col-from-label">{{translate('Subcategory')}}</label>
<div class="col-md-8">
<select class="form-control aiz-selectpicker" name="subcategory_id" id="subcategory_id" data-live-search="true" required>
</select>
</div>
</div>
My script :
function get_subcategories_by_category(){
var category_id = $('#category_id').val();
$.post('{{ route('subcategories.get_subcategories_by_category') }}',{_token:'{{ csrf_token() }}', category_id:category_id}, function(data){
$('#subcategory_id').html(null);
for (var i = 0; i < data.length; i++) {
$('#subcategory_id').append($('<option>', {
value: data[i].id,
text: data[i].name
}));
$(".aiz-selectpicker").selectpicker();
}
get_subsubcategories_by_subcategory();
});
}
$('#category_id').on('change', function() {
get_subcategories_by_category();
});
$('#subcategory_id').on('change', function() {
get_subsubcategories_by_subcategory();
});
and my controller :
public function get_subcategories_by_category(Request $request)
{
$subcategories = SubCategory::where('category_id', $request->category_id)->get();
return $subcategories;
}
But that wont work.

score validation behaves abnormally in Laravel

In my Laravel-5.8 application I have this code:
public function findScore(Request $request)
{
$userCompany = Auth::user()->company_id;
$userEmployee = Auth::user()->employee_id;
$identities = DB::table('identity')->select('id')->where('company_id', $userCompany)->where('is_current', 1)->first()->id;
$weightedscore = 0;
$weightedscore = DB::table('goals')->select(DB::raw("IFNULL(SUM(weighted_score),0) as weighted_score"))->where('identity_id', $identities)->where('employee_id', $userEmployee)->where('parent_id', $parentid)->whereNull('deleted_at')->first();
$weightedscorex = 0;
$maxscore = DB::table('goal_types')->select('max_score')->find($child->parent_id);
return response()->json([
'maxscore' => $maxscore->max_score,
'weightedscore' => $weightedscore->weighted_score,
]);
}
Route:
Route::get('get/findScore','GoalsController#findScore')->name('get.scores.all');
view (create.blade.php)
<div class="col-12 col-sm-6">
<div class="form-group">
<label class="control-label"> Goal Type:<span style="color:red;">*</span></label>
<select id="goal_type" class="form-control #error('goal_type_id') is-invalid #enderror" name="goal_type_id">
<option value="">Select Goal Type</option>
#foreach ($categories as $category)
#unless($category->name === 'Job Fundamentals')
<option hidden value="{{ $category->id }}" {{ $category->id == old('goal_type_id') ? 'selected' : '' }}>{{ $category->name }}</option>
#if ($category->children)
#foreach ($category->children as $child)
#unless($child->name === 'Job Fundamentals')
<option value="{{ $child->id }}" {{ $child->id == old('goal_type_id') ? 'selected' : '' }}> {{ $child->name }}</option>
#endunless
#endforeach
#endif
#endunless
#endforeach
</select>
<input type="hidden" id="max_score" class="form-control" >
<input type="hidden" id="weighted_score" value="0" class="form-control" >
<div class="col-12 col-sm-6">
<div class="form-group">
<label class="control-label"> Weight(%):<span style="color:red;">*</span></label>
<input type="text" name="weighted_score" id="total_weighted_score" value="{{ old('weighted_score', $goal->weighted_score) }}" placeholder="Enter weighted score here" class="form-control #error('weighted_score') is-invalid #enderror" max="120" onkeyup="checkScore(this.value)">
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">Save</button>
</div>
Javascript
<script type="text/javascript">
$(document).ready(function() {
$(document).on('change', '#goal_type', function() {
var air_id = $(this).val();
var a = $(this).parent();
var op = "";
$.ajax({
type: 'get',
url: '{{ route('get.scores.all') }}',
data: { 'id': air_id },
dataType: 'json', //return data will be json
success: function(data) {
console.log(data.maxscore);
console.log(data.weightedscore);
$('#max_score').val(data.maxscore);
$('#weighted_score').val(data.weightedscore);
},
error:function(){
}
});
});
});
</script>
<script type="text/javascript">
function checkScore(value){
let max_score = $("#max_score").val();
let weighted_score = $("#weighted_score").val();
let sumValue = parseInt(weighted_score) + parseInt(value);
if (sumValue > max_score) {
alert("sum value is greater than max score");
$("#total_weighted_score").val('');
return false;
}
}
</script>
On select dropdown change using id="goal_type", I loaded the max_score of the selected goal type.
onkeyup="checkScore(this.value)" is used to validated if the accumulated weighted score is greater than max_score. If yes, then it raises an alert:
alert("sum value is greater than max score");
This works very well in most of the cases. However, I found out that the validation is unstable. At times it doesn't work. It raises the alert even when the accumulated weighted score is less than max_score
The issue happens at various scenarios. But at times when a user tries to enter value into the text input without selecting the dropdown.
How do I resolve this?
This isn't necessarily an optimal solution, but should solve your problem. If the ajax has not returned your values yet just initialize them in a way that they wont trigger your error.
function checkScore(value) {
let max_score = $("#max_score").val();
max_score = max_score ? parseInt(max_score) : Number.MAX_SAFE_INTEGER;
let weighted_score = $("#weighted_score").val();
weighted_score = weighted_score ? parseInt(weighted_score) : 0;
let sumValue = weighted_score + parseInt(value);
if (sumValue > max_score) {
alert("sum value is greater than max score");
$("#total_weighted_score").val('');
return false;
}
}

How to Submit a Form by using a button at the same time click event on anchor link?

I have a from with button to submit it. Now i would like to pass same variables to another page to inset them in database. For that, i would like to pass the variables using an anchor link with GET with id's.
But how do it add an anchor link to the form where when i submit the form using the button the anchor link also gets triggered..
function splitAndResolve() {
var errorIds = [];
$('[name="error-selection-checkboxes"]:checked').each(function() {
errorIds.push($(this).val().split("-")[1]);
});
var taskVersion = 1;
if (errorIds.length > 0 && errorIds.length < $('[name="error-selection-checkboxes"]').length) {
var dataObj = {
'errorReportIdsToRemove': errorIds,
'user': 'user#mail.com'
};
var baseUrl = $(location).attr("href").substring(0, $(location).attr("href").lastIndexOf('/') + 1);
var splitTaskResponse = $.ajax({
url: "/task/3f2456c6b44c3b29c651f8d55c1bb34ac4da11bb6d605a00629e79f2a95c4a70/split",
type: "POST",
data: dataObj,
async: false,
error: function(xhr, status) {
if (xhr.status == 400) {
window.location.href = "/400";
alert("Failed resolving the task, please retry upon reload.");
} else {
window.location.href = "/500";
alert("Failed resolving the task, please retry upon reload.");
}
}
}).responseJSON;
var taskId = splitTaskResponse.newTaskId;
// We need to update the version without which version on the UI and the DB are different.
taskVersion = splitTaskResponse.currentTaskPostSplit.version;
window.open(baseUrl + taskId, '_blank');
}
dataObj = {
'taskResolutionStatus': $("#inputResolution").val(),
'taskResolutionStatusDetail': $("#inputResolutionDetail").val(),
'taskResolutionNote': $("#inputNotes").val(),
'changeset': $("#inputChangeset").val(),
'requiresReview': $("#requiresReviewCheckBox").is(':checked'),
'version': taskVersion
};
$.ajax({
url: "/task/3f2456c6b44c3b29c651f8d55c1bb34ac4da11bb6d605a00629e79f2a95c4a70",
type: "POST",
data: dataObj,
async: false,
error: function(xhr, status) {
if (xhr.status == 400) {
window.location.href = "/400";
alert("Failed resolving the task, please retry upon reload.");
} else {
window.location.href = "/500";
alert("Failed resolving the task, please retry upon reload.");
}
}
});
enableStatusDropdown();
return true;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="form-horizontal clearfix" onsubmit="return splitAndResolve()">
<div class="form-group">
<label for="changeset" class="col-sm-2 control-label">Changeset</label>
<div class="col-sm-10">
<input class="form-control" type="text" name="changeset" id="inputChangeset" readonly="">
</div>
</div>
<div class="form-group">
<label for="taskResolutionStatus" class="col-sm-2 control-label">Resolution</label>
<div class="col-sm-10">
<select class="form-control resolutionDropdown" name="taskResolutionStatus" id="inputResolution">
<option disabled="" selected="" value=""> -- Choose one -- </option>
<option value="ESCALATE">Escalate</option>
<option value="ALREADY_FIXED_IN_OSM">Already fixed in osm</option>
<option value="NOT_ENOUGH_INFORMATION">Not enough information</option>
<option value="NO_FIX_REQUIRED">No fix required</option>
<option value="FIXED">Fixed</option>
</select>
</div>
</div>
<div class="form-group" id="inputResolutionDetailDropdown">
<label for="taskResolutionStatusDetail" class="col-sm-2 control-label">Detail</label>
<div class="col-sm-10">
<select class="form-control resolutionDropdown" name="taskResolutionStatusDetail" id="inputResolutionDetail">
<option value="LOW_PRIORITY_AREA">Low priority area</option>
<option value="KNOWN_BUG">Known bug</option>
<option value="ERROR_BASED_ON_BAD_DATA">Error based on bad data</option>
<option value="TRUE_EXCEPTION">True exception</option>
</select>
</div>
</div>
<div class="form-group">
<label for="taskResolutionNote" class="col-sm-2 control-label">Notes</label>
<div class="col-sm-10">
<textarea class="form-control" name="taskResolutionNote" id="inputNotes" rows="3"></textarea>
</div>
</div>
<div class="form-group">
<label for="requiresReview" class="col-sm-2 control-label">Requires review</label>
<div class="col-sm-2">
<input class="form-control" name="requiresReview" type="checkbox" style="box-shadow: none" id="requiresReviewCheckBox">
</div>
</div>
<input id="taskResolutionButton" type="submit" class="btn btn-primary">
<button id="taskCancelButton" type="button" class="btn btn-default" onclick="hideResolutionOverlay()">Cancel</button>
</form>
<input id="taskResolutionButton" type="submit" class="btn btn-primary" onclick="$('#your_form_id').submit();>

How to ignore sync if value is null in laravel

I have a form where I will sync my attributes (it's like tags) but the issue is I get error while select or even not select any attribute.
Here is the error I get:
SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for
column 'attribute_id' at row 1 (SQL: insert into product_attributes
(attribute_id, product_id) values (*parameters, 65))
Before codes I need to explain what I try to do:
Select my attributes while creating new post
Give value to selected attribute
save product_id arribute_id and attribute_value in product_attributes table.
Here is my blade:
$(function() {
$('a.pl').click(function(e) {
e.preventDefault();
$('#phone').append('<div class="col-md-6"><select class="tagsselector mb-20 form-control" name="attribute[]"><option value="{{ $attribute->id }}">{{ $attribute->title }}</option></select></div><div class="col-md-6"><input name="attribute_value" class="form-control" type="text" placeholder="Value"></div>');
});
$('a.mi').click(function (e) {
e.preventDefault();
if ($('#phone input').length > 1) {
$('#phone').children().last().remove();
}
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="RegSpLeft" id="phone" style="margin-top:30px;">
<div class="col-md-6">
<label for="attributes" hidden>Attributes</label>
<select class="mb-20 form-control" name="attributes[]">
<option value="" selected>Select Attributes</option>
#foreach($attributes as $attribute)
<option value="{{ $attribute->id }}">{{ $attribute->title }}</option>
#endforeach
</select>
</div>
<div class="col-md-6">
<label for="attribute_value" hidden>attribute value</label>
<input name="attribute_value" class="form-control" type="text" placeholder="Value">
</div>
</div>
<div class="RegSpRight">
+
-
</div>
Here is my controller:
public function create()
{
$categories = Category::all();
$subcategories = Subcategory::all();
$attributes = Attribute::all();
if (is_null($attributes)) {
$attributes = [];
}
$user = Auth::user();
return view('admin.products.create', compact('user', 'categories', 'subcategories', 'attributes'));
}
My Product model:
public function attributes()
{
return $this->belongsToMany(Attribute::class, 'product_attributes', 'product_id', 'attribute_id');
}
My Attribute model:
public function products(){
return $this->belongsToMany(Product::class);
}

Ajax load data on dropdown select

There is a dropdown in my view. When I select an item in dropdown, ajax should load. So there is a table locations and it has one to many relation with contacts.
So when I select a location from locations dropdown, contact corresponding to that should load. But it is not happening.
controller:
public function location_contacts()
{
$contacts = Contact::all();
return view('partials.bookavisit_contact')->with(['contacts' => $contacts]);
}
location dropdown:
<div class="inline-control location-icon dropdown-icon">
<select class="form-control" name="visit-location" id="visitLocation" onChange="getContact(value);" >
<option date-person="lorem impsum" date-mail="lorem.ipsum#gmail.com" >Select Location</option>
#foreach($locations as $location)
<option date-person="lorem impsum" date-mail="lorem.ipsum#gmail.com" value="{!! $location->id !!}" >{!! $location->address !!}, {!! $location->city !!}, {!! $location->state !!}</option>
#endforeach
</select>
</div>
script:
#section('scripts')
<script type="text/javascript">
function getContact(val) {
var ajaxUrl = "/location_contacts";
$.ajax({
type: "POST",
url: ajaxUrl,
data:'location_id='+val,
success: function(data){
$("#contact").html(data);
}
});
}
</script>
#endsection
partial view of contact:
<div id="location-contact-info">
<div class="content-head" id="contact">
<h5 class="wow fadeInUp">Lorem ipsum</h5>
</div>
#foreach($contacts as $contact)
<div class="contact-info-group row">
<div class="contact-label">Contact Person:
<span id="location-contact-name">{{$contact->first_name}} {{$contact->last_name}}</span>
</div>
</div>
<div class="contact-info-group row">
<div class="contact-label">Email:
<span id="location-contact-mail" >{{$contact->email}}</span>
</div>
</div>
#endforeach
</div>
You have a mistake in your html, your ID contact is in your partial and need's to be in your main view like this:
<div class="inline-control location-icon dropdown-icon">
<select class="form-control" name="visit-location" id="visitLocation" onChange="getContact(value);" >
<option date-person="lorem impsum" date-mail="lorem.ipsum#gmail.com" >Select Location</option>
#foreach($locations as $location)
<option date-person="lorem impsum" date-mail="lorem.ipsum#gmail.com" value="{!! $location->id !!}" >{!! $location->address !!}, {!! $location->city !!}, {!! $location->state !!}</option>
#endforeach
</select>
</div>
<div id="contact"></div>
For that reason the $("#contact").html(data); doesn't work.
Try with that.
Regards

Categories