bug push javascript doesn't work properly? - javascript

I found a bug when entering data into an array with the push method, the bug is that the data enters index 0 (the index is only stuck to 2) can be seen in the following image:
here output from console
and here is my script :
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
let btn = $("#btn");
let target = $("#target");
let genre = $("#genre");
btn.click(function() {
target.toggleClass('hidden');
target.hasClass('hidden') ? btn.text('Opsi Lain') : btn.text('Sembunyikan');
});
genre.on('keyup', function() {
let query = $(this).val();
if (query != '' || query != null) {
let autocomplete = $("#genre-list");
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: "http://localhost/autocomplete/fetch",
method: "post",
});
$.ajax({
data: {
query: query
},
success: function(data) {
// console.log(data);
autocomplete.fadeIn();
autocomplete.html(data);
}
});
}
});
$("form").on('click', 'a', function() {
let arr = [$("div strong").text()];
arr.push($(this).text());
console.log(arr);
let value = `<strong name="genres" value="${$(this).text()}" class="inline-flex my-1.5 mr-2 bg-cool-gray-300 normal-case text-center rounded-sm pl-1.5 pr-1 h-4 no-underline text-xs py-0 tracking-normal font-normal cursor-pointer box-border items-center">${$(this).text()}<svg data-icon="cross" style="fill: currentcolor;" viewBox="0 0 16 16" class="ml-1 w-3 h-3 box-border"><path d="M9.41 8l3.29-3.29c.19-.18.3-.43.3-.71a1.003 1.003 0 00-1.71-.71L8 6.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42L6.59 8 3.3 11.29c-.19.18-.3.43-.3.71a1.003 1.003 0 001.71.71L8 9.41l3.29 3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71L9.41 8z" fill-rule="evenodd"></path></svg></strong>`;
genre.before(value);
genre.val('');
$("#genre-list").fadeOut();
});
$("form").on('click', 'svg', function() {
$(this).parent().remove();
});
</script>
and my form :
<form action="{{ route('private.store') }}" method="POST">
#csrf
<div class="shadow overflow-hidden sm:rounded-md">
<div class="px-4 py-5 bg-white sm:p-6">
<div class="ml-12 md:ml-52">
<div class="mb-5">
<label for="title" class="block text-sm font-medium text-gray-700">Title</label>
<input type="text" value="{{ old('title') }}" name="title" id="title" class="mt-1 form-input w-full md:w-3/6 text-gray-700" placeholder="title anime">
#error('title') <p class="mt-1"><span class="px-1 font-semibold rounded-full bg-red-400 text-white"> {{ $message }} </span></p>
#enderror
#error('genres') <p class="mt-1"><span class="px-1 font-semibold rounded-full bg-red-400 text-white"> {{ $message }} </span></p>
#enderror
</div>
<div class="mb-5">
<label for="genre" class="block text-sm font-medium text-gray-700">Genre</label>
<div class="w-full md:w-3/6 inline-flex flex-wrap items-center shadow-sm z-10 appearance-none bg-white border rounded-md text-base px-2 py-2">
<input type="text" value="{{ old('genre') }}" name="genre" id="genre" placeholder="What Genre ?" class=" text-gray-700 text-xs tracking-normal leading-4 flex-grow h-7 box-border" autocomplete="off">
</div>
<div id="genre-list"></div>
</div>
<div class="mb-5">
<label for="link" class="block text-sm font-medium text-gray-700">Tempat Nonton</label>
<input type="text" name="link" value="{{ old('link') }}" id="link" placeholder="https://nanime.us" class="mt-1 form-input w-full md:w-3/6 text-gray-700">
#error('link')
<p class="mt-1"><span class="px-1 font-semibold rounded-full bg-red-400 text-white"> {{ $message }} </span></p>
#enderror
</div>
<div class="mb-5">
<div class="flex items-start">
<div class="flex items-center h-5">
<input id="status" name="status" value=1 type="checkbox" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" #if (old('status')) checked #endif>
</div>
<div class="ml-3 text-sm">
<label for="status" class="font-medium text-gray-700">Perlihatkan ke Public?</label>
</div>
</div>
</div>
<div id="target" class="hidden">
<div class="mb-5">
<label for="motivasi" class="block text-sm font-medium text-gray-700">Motivasi</label>
<textarea rows="4" name="motivasi" id="motivasi" class="w-full md:w-3/6 resize-none mt-1 form-input text-gray-700">{{ old('motivasi') }}</textarea>
#error('motivasi')
<p class="mt-1"><span class="px-1 font-semibold rounded-full bg-red-400 text-white"> {{ $message }} </span></p>
#enderror
</div>
</div>
<div class="bg-white">
<button type="button" id="btn" class="mb-5 inline-flex justify-center py-1 px-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Opsi Lain
</button>
<button type="submit" class="mb-5 ml-48 sm:ml-96 md:ml-96 inline-flex justify-center py-1 px-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Create
</button>
</div>
</div>
</div>
</div>
</form>
The strong tag will be generated when the user clicks on an href link and the href link is generated from the controller, along with the contents of the controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class AutocompleteController extends Controller
{
function fetchGenre(Request $request)
{
$query = $request->get('query');
$kondisi = DB::table('ajax')
->where('for', '=', 'genre')
->where('value', 'LIKE', "{$query}%")->exists();
if ($query && $kondisi) {
$data = DB::table('ajax')
->where('for', '=', 'genre')
->where('value', 'LIKE', "{$query}%")
->get();
$output = '<div class="origin-top-right right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-100">';
foreach ($data as $row) {
$output .= '<div class="py-1"> '.$row->value.' </div>';
$output .= '</div>';
return $output;
}
}
elseif (!$kondisi) {
$err = '<div class="origin-top-right right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-100">';
$err .= '<div class="py-1"> Genre tidak di temukan! </div>';
$err .= '</div>';
return $err;
}
else {
$kosong = '';
return $kosong;
}
}
}

In answer to the original question, the problem appears to be with
$("div strong").text()
This creates an array of jQuery objects containing the the <strong> elements inside a div element, and concatenates their text content into a single string.
.text() Get the combined text contents of each element in the set of matched elements, including their descendants, or set the text contents of the matched elements.
You probably meant to push the text content of each <strong> element as a separate array entry, using something more like:
$("form").on('click', 'a', function() {
let arr = [];
$("div strong").each( function () {
arr.push($(this).text());
});
arr.push($(this).text());
console.log(arr);
});
Although untested it may help you see how to program your solution.

#Solved in the following ways
I change the location of the variable from local to global
I change the location of the variable from local to global
thank you for the intruction :)

Related

Getting the value of a nested x-data

I have a form with nested an x-data where the child has a dynamic dropdown. After fetching the data, I get null values after submitting the parent x-data.
I did some googling and found some suggestions about using Alpine.store(). I couldn't figure out, how to implement it
My form
<form action="{{ route('store.swap') }}" method="post" x-data="swapAsset" #submit.prevent="store">
#csrf
<div class="max-w-full rounded overflow-hidden shadow-lg border border-gray-900">
<div class="p-6">
<div class="font-bold text-xl mb-2">Swap from</div>
<div class="mt-1">
<select id="getcoin" name="coin" autocomplete="coin-name"
x-data="fetchTokenBalance()" #change="fetch_token_balance" x-model="formData.coin"
class="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<option hidden>Choose</option>
#foreach ($userAssets as $up)
<option id="getcoin{{ $up->id }}" value="{{ $up->id }}">{{ $up->token_name }}</option>
#endforeach
</select>
</div>
<div class="mt-4">
<x-input
type="text"
id="amount"
x-model="formData.amount"
x-text="formData.amount"
name="amount"
class="block mt-1 w-full"
:value="old('amount')"
placeholder="0.00"/>
</div>
<a class="text-sm text-gray-600 hover:text-gray-900" href="javascript:void(0)">
{{ __('Max') }} <span id="maxValue"></span>
</a>
</div>
</div>
<div class="max-w-full rounded overflow-hidden shadow-lg border border-gray-900">
<div class="p-6">
<div class="font-bold text-xl mb-2">Swap to</div>
<div class="mt-1">
<select
id="tocoin"
name="tocoin"
x-model="formData.tocoin"
class="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
>
#foreach ($wallets as $wallet)
<option value="{{ $wallet->id }}">{{ $wallet->name }}</option>
#endforeach
</select>
</div>
</div>
</div>
<div class="mt-8 mb-6 ">
<x-button class="w-full py-4 px-6 text-center" style="display: block">Swap Assets</x-button>
</div>
</form>
The Child x-data works fine but the parent x-data return null
swapAsset function
function swapAsset() {
return {
formData: {
'coin': '',
'amount': '',
'tocoin': ''
},
msg: '',
store(e) {
e.stopImmediatePropagation();
this.msg = ''
axios.post("{{ route('store.swap') }}", {
coin: this.formData.coin,
tocoin: this.formData.tocoin,
amount: this.formData.amount
})
.then((response) => {
console.log(response);
console.log('Test: '+this.formData.coin);
})
.catch((error) => {
console.log(error)
console.log('Error: '+this.formData.amount);
})
}
}
}
function fetchTokenBalance() {
return {
formData: {
coin: '',
},
fetch_token_balance(e) {
e.stopImmediatePropagation();
console.log(this.coin);
axios.get('user/' + this.formData.coin, {
coin: this.formData.coin
}).then((response) => {
console.log(response);
const result = response.data;
document.getElementById('maxValue').innerHTML = result.token_balance + ' ' + result.token_name
document.getElementById("getcoin" +this.formData.coin).selected = "true"
}).catch((error) => {
console.log(error);
})
}
}
}
$('#maxValue').on('click', () => {
console.log($('#maxValue').text());
let str = $('#maxValue').text();
let str_without_token_name = str.split(' ');
$("#amount").val(str_without_token_name[0]);
console.log(str_without_token_name[0])
})

Modal doesn't open on all buttons

As my title already says, I have an issue with a modal not opening on all buttons.
Here is the situation:
I have a page that displays all applications a user has sent for different jobs. So it may be just one, or up to whatever.
It looks like this:
Now if the user wants to cancel the application he can press the button "Bewerbung zurückziehen", then the modal opens to give a heads up that all data will be lost and if he is sure, in the modal he can confirm it or go back. Everything works fine for the first post on the site, but for all other posts just nothing happens, so the modal doesn't open.
Here is my code:
The blade file that displays all posts:
#foreach($bewerbungen as $bewerbung)
#foreach($stellenanzeigen_names as $stellenanzeigen_name)
#if($bewerbung->Stellenanzeigen_ID === $stellenanzeigen_name->Stellenanzeigen_ID)
<div
class="p-10 grid-cols-3 grid-rows-3 gap-4 shadow-2xl mb-10 bg-gradient-to-r from-green-400 to-blue-500 border-solid border-2 border-black rounded-lg">
<!--Card 1-->
<div
class="overflow-hidden row-span-3 bg-gray-100 shadow-2xl border-solid border-2 border-gray-500 rounded-lg">
<div class="pt-4 pl-4">
{{ $stellenanzeigen_name->Titel }}
<hr class="border-black">
</div>
<div class="pt-4 pl-8 font-medium text-xl font-bold font-serif">
ID der Bewerbung: {{ $bewerbung->Bewerbung_ID }}</div>
<div class="pt-4 pl-8 pb-3 font-medium text-xl font-bold font-serif">
ID der Stellenanzeige: {{ $bewerbung->Stellenanzeigen_ID }}</div>
<div class="w-1/4 mb-4 pl-4">
<div class="font-medium text-base font-bold font-serif mb-4 pb-3">
<button type="submit" id="delete_appl_btn" name="delete_appl_btn"
class="mb-4 pb-3 w-full text-white px-4 py-3 rounded text-base font-medium
bg-gradient-to-r from-green-400 to-blue-500 float-right shadow transition
duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-100
shadow-2xl border-2 w-full p-4 rounded-lg">
Bewerbung zurückziehen
</button>
</div>
</div>
</div>
</div>
#endif
#endforeach
#endforeach
Here is the code for the modal:
<div id="delete_application_modal" class="modal fixed ml-96 top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white hidden">
<div class="mt-3 text-center text-xl">
Bewerbung zurückziehen
<div class="text-center text-sm mt-4">
</div>
</div>
<div class="items-center px-4 py-3">
<label for="delete_application" class="sr-only">Bewerbung zurückziehen</label>
<form action="{{ route('delete', $bewerbung->Bewerbung_ID) }}" method="post">
#csrf
<button type="submit" id="ok_btn" class="mb-4 pb-3 w-full text-white px-4 py-3 rounded text-base font-medium
bg-gradient-to-r from-green-400 to-blue-500 float-right shadow transition
duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-100
shadow-2xl border-2 w-full p-4 rounded-lg">
Bewerbung zurückziehen
</button>
</form>
</div>
<div class="items-center px-4 py-3">
<button id="back_btn_tel" class="mb-4 pb-3 w-full text-white px-4 py-3 rounded text-base font-medium
bg-gradient-to-r from-green-400 to-blue-500 float-right shadow transition
duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-100
shadow-2xl border-2 w-full p-4 rounded-lg">
zurück
</button>
</div>
</div>
#if(session()->has('message'))
<div class="alert alert-success">
{{ session()->get('message') }}
</div>
#endif
<script>
var delete_appl_modal = document.getElementById("delete_application_modal");
var open_modal = document.getElementById("delete_appl_btn");
var back_btn = document.getElementById("back_btn_tel");
open_modal.onclick = function () {
delete_appl_modal.style.display = "block";
}
back_btn.onclick = function () {
delete_appl_modal.style.display = "none";
}
window.onclick = function (event) {
if (event.target == modal) {
delete_appl_modal.style.display = "none";
}
}
</script>
Honestly, I have zero clue why it works for the first but not for the others, they have the same buttons, with the same name, id & everything.
Maybe one of you had a similar issue. I wish you all happy holidays!
Edit:
New code to open the modal:
<script>
var delete_appl_modal = document.querySelector('#cancel_appl_modal');
var open = document.querySelector('#open_btn');
var back_btn = document.querySelector('#back_btn_tel');
open.onclick = function () {
delete_appl_modal.style.display = "block";
}
back_btn.onclick = function () {
delete_appl_modal.style.display = "none";
}
window.onclick = function (event) {
if (event.target == modal) {
delete_appl_modal.style.display = "none";
}
}
</script>
When I use querySelectorALl then the first one doesn't work anymore as well
The id property is expected to be unique within a page, so when using getElementById once an element with that id has been located it doesn't continue searching for others.
As you have multiple button elements that you want to target, you will need to us something like querySelectorAll or getElementsByClassName to target every element that should trigger the modal to open.
An example to get you on the right direction.
<button class="open-modal">Button A</button>
<button class="open-modal">Button B</button>
<button class="open-modal">Button C</button>
let buttons = document.querySelectorAll('.open-modal');
buttons.forEach(button => {
button.addEventListener('click', function (event) {
// this is where you would open the modal
// delete_appl_modal.style.display = 'block';
console.log(event.target.innerHTML);
})
});
Example JSFiddle

How to display an error message in django formset with ajax

I'm trying to submit a django formset using ajax, but the problem is that I can't iterate the error fields and it give me each error to its form and field!
class Vistor(models.Model):
admin = models.ForeignKey(User,on_delete=models.PROTECT)
full_name = models.CharField(max_length=150)
dob = models.DateField(max_length=14)
city = models.ForeignKey(City,on_delete=models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(fields=['full_name','dob','city'],name='full_information')
]
And also I've used ModelForm
class VistorForm(forms.ModelForm):
city = forms.ModelChoiceField(
queryset=City.objects.all())
class Meta:
model = Vistor
fields = [
'full_name','dob','city'
]
VistorFormSet = modelformset_factory(Vistor,form=VistorForm,extra=1,can_delete=True)
non_fields_error defined as __all__ in ajax call error messages
#login_required
def add_vistor(request):
formset = VistorFormSet(queryset=Vistor.objects.none())
if request.is_ajax() and request.method == 'POST':
formset = VistorFormSet(request.POST)
if formset.is_valid():
for form in formset:
obj = form.save(commit=False)
if form.cleaned_data !={}:
obj.admin = request.user
obj.save()
formset = VistorFormSet(queryset=City.objects.none())
return JsonResponse({'success':'success'})
else:
return
JsonResponse({'success':False,'error_msg':formset.errors,'error_code':'invalid'})
return render(request,'vistors/add_vistor.html',{'formset':formset})
my html + js
//for adding new form
$('#addButton').click(function() {
var form_dex1 = $('#id_form-TOTAL_FORMS').val();
$('#form').append($('#formset').html().replace(/__prefix__/g,form_dex1));
$('#id_form-TOTAL_FORMS').val(parseInt(form_dex1) + 1);
});
//ajax submit form
const form = document.getElementById('post-form')
form.addEventListener("submit",submitHandler);
function submitHandler(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url 'vistors:add_vistor' %}',
data : $('#post-form').serialize(),
dataType: 'json',
success: successFunction,
});
}
function successFunction(data) {
console.log(data.success=='success')
if (data.success=='success') {
alertify.success("added")
form.reset();
}
else if(data.error_code=='invalid'){
console.log(data.error_msg.length)
for(var i=0; i < data.error_msg.length;i++){
console.log(data.error_msg)
if(key == 'full_name'){
document.getElementById('full_name_error').removeAttribute('hidden')
document.getElementById('full_name_error').innerHTML = data.error_msg[key][0]
}
if(key == 'dob'){
document.getElementById('dob_error').removeAttribute('hidden')
document.getElementById('dob_error').innerHTML = data.error_msg[key][0]
}
if(key == 'city'){
document.getElementById('city_error').removeAttribute('hidden')
document.getElementById('city_error').innerHTML = data.error_msg[key][0]
}
if(key == '__all__'){
document.getElementById('full_name_error').removeAttribute('hidden')
document.getElementById('full_name_error').innerHTML = data.error_msg[key][0]
}
}
}
}
<div class="z-30 w-full p-2 mt-3 bg-white bg-opacity-75 shadow-lg md:mt-0 md:top-32 rounded-xl md:absolute md:right-0" >
<button id="addButton" class="px-4 py-1 pb-2 text-white focus:outline-none header rounded-xl">
add new form
<i class="bi bi-plus"></i>
</button>
<form id="post-form" method="POST" class="mt-2 ">{% csrf_token %}
{% for form in formset.forms %}
{{ form.id }}
<div id="form" class="grid md:grid-cols-3 gap-16 md:gap-x-3 md:gap-y-8">
{{formset.management_form}}
<!-- first form -->
<div class="relative p-2 bg-gray-900 bg-opacity-25 border border-gray-900 rounded-xl pb-14">
<div class="relative groupinput bglightpurple rounded-xl">
<label class="absolute mt-1 mr-2 text-xs text-white top-1">full name</label>
{{form.full_name | add_class:'w-full pt-6 pb-1 pr-2 text-white bg-transparent focus:outline-none'}}
<p class="w-full pb-2 pr-2 text-white rounded-xl" id="full_name_error" hidden>error</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 md:gap-1">
<div class="relative mt-2 groupinput bglightpurple rounded-xl">
<label class="absolute mt-1 mr-2 text-xs text-white top-1">dob</label>
{{form.dob | add_class:'w-full pt-6 pb-1 pr-2 text-white bg-transparent focus:outline-none'}}
<p class="w-full pb-2 pr-2 text-white rounded-xl" id="dob_error" hidden>error</p>
</div>
<div class="flex flex-wrap justfiy-between md:gap-1">
<div class="w-9/12 relative mt-2 groupinput bglightpurple rounded-xl">
<label class="absolute mt-1 mr-2 text-xs text-white top-1">city </label>
{{form.city | add_class:'w-full pt-6 pb-1 pr-2 text-white bg-transparent focus:outline-none'}}
<p class="w-9/12 pb-2 pr-2 text-white rounded-xl" id="city_error" hidden>error</p>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
<div id="formset" class="grid md:grid-cols-3 gap-16 md:gap-x-3 md:gap-y-8" style="display: none;">
<!-- formset -->
<div class="relative p-2 bg-gray-900 bg-opacity-25 border border-gray-900 rounded-xl pb-14">
<div class="relative groupinput bglightpurple rounded-xl">
<label class="absolute mt-1 mr-2 text-xs text-white top-1">full name</label>
{{formset.empty_form.full_name | add_class:'w-full pt-6 pb-1 pr-2 text-white bg-transparent focus:outline-none'}}
<p class="w-full pb-2 pr-2 text-white rounded-xl" id="full_name_set_error" hidden>error</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 md:gap-1">
<div class="relative mt-2 groupinput bglightpurple rounded-xl">
<label class="absolute mt-1 mr-2 text-xs text-white top-1">dob</label>
{{formset.empty_form.dob | add_class:'w-full pt-6 pb-1 pr-2 text-white bg-transparent focus:outline-none'}}
<p class="w-full pb-2 pr-2 text-white rounded-xl" id="dob_set_error" hidden>error</p>
</div>
<div class="relative mt-2 groupinput bglightpurple rounded-xl">
<label class="absolute mt-1 mr-2 text-xs text-white top-1">city </label>
{{formset.empty_form.city | add_class:'w-full pt-6 pb-1 pr-2 text-white bg-transparent focus:outline-none'}}
<p class="w-full pb-2 pr-2 text-white rounded-xl" id="city_set_error" hidden>error</p>
</div>
</div>
</div>
</div>
<button type="submit" class="px-6 py-1 mt-6 text-white rounded-lg header ">save</button>
</form>
</div>
But I can't do that , and errors returns in an array dictionary , for example : for the constraint fields (unique fields together) it returns this in the console !

Why my function in html code is not being called?

I'm working on a Laravel Livewire project which uses TailwindCSS and AlpineJS. But my issue is about my setCountry() function not being called. I can see the parameters are being correctly passed but the function itself is not being called. The toggleCountriesHandler() function is working nicely.
I bet it is something under my nose, but I still can't figure it out, and I'm a begginer in programming.
Here's my code snippet:
toggleCountriesHandler = () => {
let toggleCountries = document.getElementById("countriesOpen");
if (toggleCountries.style.display === "none") {
toggleCountries.style.display = "block";
} else {
toggleCountries.style.display = "none";
}
}
setCountry = (country_id, country_code, country_name) => {
document.getElementById("country-id").value = country_id;
document.getElementById("selected-country").innerHTML = "<img class='w-5 h-5 rounded-full' src='img/flags/16/" + country_code + ".png'>" + "<span class='block ml-3 font-normal truncate'>" + country_name + "</span>";
document.getElementById("countriesOpen").style.display = "none";
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.2.0/tailwind.min.css" rel="stylesheet" />
<span class="block text-sm font-medium text-gray-700 transform translate-y-5">{{__("Country")}</span>
<div style="height: 42px;" class="relative flex items-center justify-center w-full pl-3.5 pr-10 text-left bg-white border border-gray-300 rounded-md shadow-sm cursor-default focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<button onclick="toggleCountriesHandler()" class="block w-full truncate focus:outline-none">
<label id="selected-country" class="flex flex-row items-center text-gray-500">{{__("Select your country")}}</label>
</button>
<div class="absolute top-0 right-0 w-full mt-12 bg-white rounded-md shadow-lg sm:bg-white">
<input id="country-id" type="hidden" name="country_id">
<ul id="countriesOpen" style="display: none;" class="py-1 overflow-auto text-base rounded-md sm:border max-h-60 ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
#foreach(DB::table('countries')->get() as $country)
<li role="option" class="relative ">
<button onclick="setCountry({{ $country->id }}, '{{ $country->code }}', '{{ $country->name }}')" type="button" class="flex items-center w-full py-2 pl-3 space-x-3 cursor-default select-none text-extrading-text-primary sm:text-gray-900 pr-9 focus:outline-none hover:bg-indigo-600 hover:text-white">
<img class="w-5 h-5 rounded-full" src="{{ asset('img/flags/16/' . $country->code . '.png') }}">
<span class="block font-normal truncate">
{{$country->name}}
</span>
</button>
</li>
#endforeach
</ul>
</div>
</div>
I am posting my comment as an answer to close this question.
const toggletoggleCountriesHandler=()=>{}
const is usually used for the function declarations , since people don't change it.
Still you can use var , let also for declaration

Binded input value does not appear in request

I am trying to bind backAfterSaveStatus value to hidden input and for some reason then form is submited backAfterSave value is null.
After that I go back and submit form again - backAfterSave value is 1. Where is the problem?
I tried same thing without prevent and submit() but it's not working still. Also I had dumped div with x-text and code makes hidden input 1 before form submit. What I am doing wrong?
<form action="<...>" method="post">
<div x-data="{
backAfterSaveStatus: '',
backAfterSave () {
this.backAfterSaveStatus = '1';
document.querySelector('form.withBackAfterSave').submit();
}
}">
<input name="backAfterSave" :value="backAfterSaveStatus">
<div>
<span>
<button x-on:click.prevent="backAfterSave()" type="submit">
Save & back
</button>
</span>
<span>
<button type="submit">
Save
</button>
</span>
</div>
</div>
</form>
I want same result as below:
let buttonBackAfterSave = document.getElementById('button-back-after-save');
if (buttonBackAfterSave) {
buttonBackAfterSave.addEventListener('click', () => document.getElementById('input-back-after-save').value = 1);
}
The problem is the form being submitted "too fast" (the backAfterSaveStatus value isn't done binding to the input). Use $nextTick so Alpine waits until the value is properly changed.
<form method="post" class="withBackAfterSave">
#csrf
<div x-data="{
backAfterSaveStatus: '',
backAfterSave () {
this.backAfterSaveStatus = '1';
this.$nextTick(() => { document.querySelector('form.withBackAfterSave').submit() });
}
}">
<input name="backAfterSave" x-bind:value="backAfterSaveStatus">
<div>
<span>
<button x-on:click.prevent="backAfterSave()" type="submit">
Save & back
</button>
</span>
<span>
<button type="submit">
Save
</button>
</span>
</div>
</div>
</form>
Thank you! I don't use x-ref because these buttons are in separate layouts file, so I can't move it outside x-data range. My final code:
<div class="pt-5">
<div class="flex justify-end" x-data="{
backAfterSave: 0
}">
<input type="hidden" name="backAfterSave" :value="backAfterSave">
<button type="button"
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
{{ __('Cancel') }}
</button>
<button type="submit"
#click.prevent="backAfterSave=1; $nextTick(() => {
document.querySelector('form.with-back-after-save').submit()
})"
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
{{ __('Save & back') }}
</button>
<button type="submit"
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-teal-600 hover:bg-teal-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-teal-500">
{{ __('Save') }}
</button>
</div>
</div>
Just released that I could use simple button with custom name and given value.. No javascript was needed :)
<button type="submit" name="back-after-submit" value="1">Save</button>

Categories