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])
})
Related
I have created this component and use $emit to call getNames from other file:
<div class="mt-1 relative rounded-md shadow-md">
<input
v-model="ticker"
#keydown.enter="addClick"
#input="getNames"
type="text"
name="wallet"
id="wallet"
class="block w-full pr-10 border-gray-300 text-gray-900 focus:outline-none focus:ring-gray-500 focus:border-gray-500 sm:text-sm rounded-md"
placeholder="DOGE"
/>
</div>
<div class="flex bg-white shadow-md p-1 rounded-md shadow-md flex-wrap">
<span
class="inline-flex items-center px-2 m-1 rounded-md text-xs font-medium bg-gray-300 text-gray-800 cursor-pointer"
v-for="t of getNames()"
:key="t.name"
#click="pushName(t)"
>
{{ t }}
</span>
</div>
import addButton from "./addButton.vue";
export default {
components: {
addButton,
},
data() {
return {
ticker: "",
};
},
methods: {
addClick() {
this.$emit("add-ticker", this.ticker);
this.ticker = "";
},
getNames(){
this.$emit("get-name", this.ticker);
}
It's working but it doesn't return value to my component and I don't get list of names, it worked successful without component. In other file i have this code:
<add-ticker #get-name="getNames" #add-ticker='addClick'/>
getNames(ticker) {
let filtred = this.coinNames.filter((filtered) =>
filtered.toUpperCase().startsWith(ticker.toUpperCase())
);
console.log(filtred.slice(0,4))
return filtred.slice(0, 4);
I have 2 objects size and colors later it will be more. I have a dynamic field based on those attributes. The problem is I can store the first field values but when I add the second dynamic field the previous data is removed. I am trying to store all the previous data values when the state update.
If you wish, you can see my live code: https://codesandbox.io/s/bold-http-0yh6m3?file=/src/App.js
My states and data: addAttributes for showing values and fakeAttributes are the detailed value of addAttributes.
const [attributes, setAttributes] = useState([{ label: '', value: 1 }])
const [newAttributes, setNewAttributes] = useState([{ label: '', value: 1 }])
// Data
const addAttributes = [
{ label: 'colors', value: 1 },
{ label: 'size', value: 2 },
]
// Attributes data
const fakeAttributes = [{
label: 'colors',
object: [
{ label: 'Black', value: 1 },
{ label: 'Green', value: 2 },
]
},
{
label: 'size',
object: [
{ label: 'M', value: 1 },
{ label: 'S', value: 2 },
]
}
]
I am using react-select npm, The below code is adding a dynamic field. setNewAttributes storing the values into the newAttributes state. When I console.log(newAttributes) it returns the value correctly but as soon as I add a new field the previous data removing. I didn't create any function for adding dynamic fields I have tried this way.
{fakeAttributes.map((attr) => {
const item = attributes.filter((list) => {
return list.label === attr.label;
})[0];
if (item) {
return <div key={attr.label} className="basis-1/4">
<label className="block text-sm font-medium text-gray-700 mb-3"> {attr.label} </label>
<Select options={attr.object} onChange={(e: any) => setNewAttributes(e)} className="shadow appearance-none border rounded w-full text-gray-700 leading-tight focus:outline-none focus:shadow-outline" isMulti /></div>
}
})}
I have tried like this way, If I use dependency it calls the value every time but did not work properly:
useEffect(() =>{
setNewAttributes((oldArray):any => [...oldArray, newAttributes]);
}, [newAttributes])
My expected result is similar to this array object.
[
0:{label: 'colors', SelectedValue: {{label: "green"}},
1:{label: 'size', SelectedValue: {{label: "M"}, {label: "S"}}
]
My full code:
import React, { useEffect, useState } from 'react';
import "file-upload-with-preview/dist/file-upload-with-preview.min.css";
import DateTimePicker from 'react-datetime-picker';
import Select from 'react-select';
import './AddProduct.css'
import AddRemoveMultipleInputFields from './AddRemoveMultipleInputFields';
interface IAppProps {
}
const AddProduct: React.FunctionComponent<IAppProps> = (props) => {
const [date, setDate] = useState(new Date())
const [size, setSize] = useState()
const [attributes, setAttributes] = useState([{ label: '', value: 1 }])
const [newAttributes, setNewAttributes] = useState([{ label: '', value: 1 }])
const [selectedImages, setSelectedImages] = useState([]);
// const [arr, setArr] = useState([])
const onSelectFile = (event: any) => {
const selectedFiles = event.target.files;
const selectedFilesArray = Array.from(selectedFiles);
const imagesArray: any = selectedFilesArray.map((file: any) => {
return URL.createObjectURL(file);
});
setSelectedImages((previousImages) => previousImages.concat(imagesArray));
};
// Data need to break and store label info in another variable and add value dynamically
const addAttributes = [
{ label: 'colors', value: 1 },
{ label: 'size', value: 2 },
]
// Attributes data
const fakeAttributes = [{
label: 'colors',
object: [
{ label: 'Black', value: 1 },
{ label: 'Green', value: 2 },
]
},
{
label: 'size',
object: [
{ label: 'M', value: 3 },
{ label: 'S', value: 4 },
]
}
]
useEffect(() =>{
setNewAttributes((oldArray): any => [...oldArray, ...attributes]);
},[])
// const previousValue = () => {
// setNewAttributes((oldArray): any => [...oldArray, ...attributes]);
// }
// console.log(newAttributes);
const Countries = [
{ label: "M", value: 355 },
{ label: "S", value: 54 },
{ label: "XL", value: 43 },
{ label: "XXL", value: 61 },
];
return (
<div className=" ">
<div className="mt-5 md:mt-0 md:col-span-2">
<form action="#" method="POST">
<div className="grid grid-cols-3 gap-4">
<div className="col-span-2">
<div className="shadow sm:rounded-md sm:overflow-hidden">
<div className="px-4 py-5 bg-white space-y-6 sm:p-6">
{/* TITLE */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-3"> Title </label>
<input className="shadow appearance-none border rounded w-full py-3 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="name" type="text" placeholder="Title" />
</div>
{/* SHORT DETAILS */}
<div className="flex flex-row gap-6">
<div className="basis-1/2">
<label className="block text-sm font-medium text-gray-700 mb-3"> Brand </label>
<input className="shadow appearance-none border rounded w-full py-3 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="name" type="text" placeholder="Brand " required />
</div>
<div className="basis-1/2">
<label className="block text-sm font-medium text-gray-700 mb-3"> Categories </label>
<Select onChange={(e: any) => setSize(e)} className="shadow appearance-none border rounded w-full text-gray-700 leading-tight focus:outline-none focus:shadow-outline" options={Countries} isMulti />
</div>
</div>
<div className="flex flex-row gap-6">
<div className="basis-1/4">
<label className="block text-sm font-medium text-gray-700 mb-3"> Regular Price </label>
<input className="shadow appearance-none border rounded w-full py-3 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="name" type="text" placeholder="Regular Price " required />
</div>
<div className="basis-1/4">
<label className="block text-sm font-medium text-gray-700 mb-3"> Sale Price </label>
<input className="shadow appearance-none border rounded w-full py-3 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="name" type="text" placeholder="Sale Price" />
</div>
<div className="basis-1/4">
<label className="block text-sm font-medium text-gray-700 mb-3"> Offer last date and time </label>
<DateTimePicker className='shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline' onChange={setDate} value={date} />
</div>
</div>
<div className='flex flex-row gap-6'>
{fakeAttributes.map((attr) => {
const item = attributes.filter((list) => {
return list.label === attr.label;
})[0];
if (item) {
return <div key={attr.label} className="basis-1/4">
<label className="block text-sm font-medium text-gray-700 mb-3"> {attr.label} </label>
<Select options={attr.object} onChange={(e: any) => setNewAttributes(e)} className="shadow appearance-none border rounded w-full text-gray-700 leading-tight focus:outline-none focus:shadow-outline" isMulti /></div>
}
})}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-3"> Description </label>
<textarea className="shadow form-textarea mt-1 block w-full border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" rows={5} placeholder="Description"></textarea>
</div>
</div>
</div>
</div>
<div className="shadow sm:rounded-md sm:overflow-hidden bg-white px-4 py-5 bg-white space-y-6 sm:p-6">
<section className='image-upload'>
<label className='mt-1 flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md flex-col items-center '>
<div>
<svg className="mx-auto h-12 w-12 text-gray-400" stroke="currentColor" fill="none" viewBox="0 0 48 48" aria-hidden="true">
<path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</div>
<br />
<div>
<span>+ Add Images up to 10 images</span>
<input
type="file"
name="images"
onChange={onSelectFile}
multiple
accept="image/png , image/jpeg, image/webp"
/>
</div>
</label>
<br />
{selectedImages.length > 0 &&
(selectedImages.length > 10 ? (
<p className="error">
You can't upload more than 10 images! <br />
<span>
please delete <b> {selectedImages.length - 10} </b> of them{" "}
</span>
</p>
) : (
''
))}
<div className="images flex flex-row gap-6">
{selectedImages &&
selectedImages.map((image, index) => {
return (
<div key={image} className="image basis-1/4">
<div className='flex justify-between'>
<button
onClick={() =>
setSelectedImages(selectedImages.filter((e) => e !== image))
}
>
x
</button>
<p>{index + 1}</p>
</div>
<img className='shadow sm:rounded-md' src={image} height="200" alt="upload" />
</div>
);
})}
</div>
</section>
<div className="basis-1/4">
<label className="block text-sm font-medium text-gray-700 mb-3"> Attributes </label>
<Select onChange={(e: any) => setAttributes(e)} className="shadow appearance-none border rounded w-full text-gray-700 leading-tight focus:outline-none focus:shadow-outline" options={addAttributes} isMulti />
</div>
<div className=" py-3 text-right ">
<button type="submit" className="inline-flex justify-center py-2 px-4 border border-transparent drop-shadow-md 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">Publish</button>
</div>
</div>
</div>
</form>
</div>
</div>
)
};
export default AddProduct;
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 !
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 :)
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