Suppose you have a form in your Laravel project that when submit sends the data to the server for processing. But when the form is submitted, your browser has to refresh the whole page which means that it needs to load all the CSS, JS, and image files again and also render all the HTML in the browser again. So you need to convert this POST request into an AJAX request to prevent the page from reloading.
I am using a form with a text field and an input type file so you can know how to send an image in an AJAX request.
CSRF field is required in Laravel for POST requests. onsubmit event is attached to the form and it will call a Javascript function to send an AJAX request. Now we need to create that function in Javascript that will send an AJAX request to the server along with all the data in the form:
First, we are validating that the request must have name and file fields and the file must be an image. Then we are inserting the data from the text field in the users table. You can find the sample database in the attachments below.
Then we are storing the image in a public/storage folder. You need to run the following command in order to make this work:
1
php artisan storage:link
Lastly, we are sending the response back in JSON format. That’s how you can convert a POST request into an AJAX request in Laravel.
When you submit a form with a POST request and if you refresh that page, you will see an alert that says “Confirm form resubmission”. This is not good for the user experience. You cannot use the GET method because it will make the URL look bad. But we still need to prevent this form resubmission alert dialog.
So using this technique, you can achieve both. Submit the form without making the URL bad, and prevent the “form resubmission” alert.
Suppose you have a form with an input field that sends a POST request like the following:
Attach an event named “onsubmit” to the form tag that calls a Javascript function named “onFormSubmit”. The return statement is used to prevent the form from submitting. Now, create that function in Javascript:
Comments have been added with each line for an explanation. You can write all your form fields in the data object. If you have an input type=”file” field in your form, you can add it to the data object by calling the files property like the following:
1
2
3
vardata = {
"image": form.image.files[0]
};
For multiple files, you can simply remove the [0] from the above line and it will add all files in the data object.
Now on server-side, do the following to get the values:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
// get in server side
$my_form= $_COOKIE["my_form"];
// decode from JSON
$my_form= json_decode($my_form);
// get single value
$name= $my_form->name;
print_r($name);
?>
As we were storing the values in cookies using Javascript, so we can get them from cookies using PHP.
As we were storing the values in JSON string using Javascript. So, we can get them by decoding from JSON string using PHP.
That’s how you can prevent the “form resubmission” alert and also keep your URL clean from GET request.
Suppose you have an associative array in PHP with key-value pair. If you loop through it, all the values will be displayed in the order they are added to the array. To learn how to customize the sorting of an associative array, keep reading this. We will teach you how you can custom sort an associative array in PHP. You can easily sort the numeric key though.
We will use a database called “classicmodels”, which can be found in the source files attached below. First, we will connect with the database and get all the columns of the desired table.
$result= mysqli_query($conn, "SELECT * FROM customers");
$columns= [];
while($row= mysqli_fetch_object($result))
{
foreach($rowas$col_name=> $col_value)
{
array_push($columns, $col_name);
}
break;
}
mysqli_data_seek($result, 0);
If you do print_r($columns); after this, then you will see all the column names of that table. Now create an array that holds the desired sorting of columns.
The key of each element is the name of the column in the database. And the value is the text that will be shown against that column. Now comes the most important part, to display the first table row which is usually the heading, do a foreach loop on this array and display the value in TH:
1
2
3
4
5
6
7
8
9
<table>
<tr>
<?phpforeach ($columns_order as $key => $value): ?>
<th>
<?phpecho $value; ?>
</th>
<?phpendforeach; ?>
</tr>
</table>
To display the data as in new order, loop through each record in the database. Then run a nested foreach loop like above, and show the values based on the key of an associative array:
Try changing the order of columns from $columns_order array. You can also try deleting columns from this array, so if you want to remove some columns from the table tag, you can simply remove that from $columns_order array.
That’s how you can custom sort an associative array in PHP. Learn how to custom sort data from MySQL database following this tutorial.
When you are calling an AJAX in Laravel, you will see a “500 – Internal Server Error” if there is an error in your PHP code. To see the actual error, kindly follow this article. We will teach you in this tutorial, how you can view error from your AJAX request.
Suppose I am calling an AJAX request in Laravel using core Javascript (no jQuery), then your code will be like this:
Line #2: I have opened the AJAX request with the POST method and the URL where the request will be sent. The third parameter (true, false) is the asynchronous boolean.
Note: All modern browsers recommend this value to be true.
Line #4: An event listener that will be called each time the status of request is changed.
#5: Check if the request is successful and the response has been received from server.
#6: Display the response from the server in browser console.
#9: Check if there is an internal server error. If yes, then display that error in line #10.
#14: New form data object is created that will send the data with an AJAX request.
#15: A CSRF (cross-side request forgery) token is appended in the form data object. We will create that meta tag later in this article.
Note: Every POST request in Laravel requires a CSRF token to be sent along with request.
Line #16: Sending the AJAX request along with form data object values.
You can create the hidden base URL and CSRF token tags as follows:
Now, whatever the error you are having on your server-side, in route, or in the controller, you will see that in your browser console window.
jQuery AJAX
If you are using jQuery to send an AJAX request and not seeing the actual error from your server-side, then change your jQuery AJAX function to the following:
Now, if you have an error in your AJAX request, you can view it in the “error” callback. Learn how to convert a simple POST request into an AJAX request following this tutorial.
SQLite is used to store the data locally inside the app in SQL structure. It is a relational local database. You can use this database to store data inside the app using Swift and Swift UI. We will be creating a simple search bar in an iOS app in Swift UI to search animals from an array and save the user’s searched strings in the SQLite database.
We will be using a library called SQLite by Stephen Celis. To install this library, you must have Cocoapods installed in your system.
Installation
You can install Cocoapods in your system by simply running the following command in your terminal:
1
sudogem installcocoapods
First, you need to open a command prompt (Terminal) at the root of your XCode project and run the following command in it:
1
pod init
Now you will see a new file created at the root of your project named Podfile. Open that file in your text editor and add the line to install the library. Following will be the content of your Podfile:
1
2
3
4
5
6
7
8
9
10
11
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'SQLite_Database'do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for SQLite_Database
pod 'SQLite.swift', '~> 0.12.0'
end
After that, run the following command in your Terminal to install this library:
1
pod update
Once installed, close your XCode and re-open but this time double-click on the file which has an extension “.xcworkspace“. This file will be created only after the pod has been installed/updated.
Create a search bar
First, we will create a search bar using TextField. Then, when the user hits submit, we will send the searched value in the next view.
In the second view, we will get the value from the text field of the first view and search that value in an array. Then, display all the records that matched the searched string and display them in the list view.
Create a state variable in your content view:
1
2
3
4
5
// variable to goto search view
@Statevar gotoSearchPage: Bool = false
// value that is searched from the text field
@Statevar searchedText: String = ""
Following will be the content of your content view’s body:
This will create a text field where you can enter your query, on hitting the “search icon” it should take you to the search view which we will create in the next step.
Create a search view
Now, we need to create a search view where we will perform the searching and display the filtered records in a list view.
// when using @Binding, use this in preview provider
@Statestaticvar searchedText: String = ""
staticvar previews: some View {
SearchView(searchedText: $searchedText)
}
}
Comments have been added on each line to explain each line individually. Now, at this point, you will be able to perform the search and see the animals which contain the name field that matches with the text field value you entered in the first view.
Show search history
Now, we need to show the search history in the content view. For that, first, we have to save each searched string in the SQLite database.
Create a separate class named “DB_Manager” that will hold all the functions for the SQLite database.
let animal: AnySequence<Row> = trydb.prepare(animals.filter(name.lowercaseString == searchedText.lowercased()))
// get row
animal.forEach({ (rowValue) in
isExists = true
})
} catch{
print(error.localizedDescription)
}
returnisExists
}
// add a new row in SQLite
publicfunc addAnimal(nameValue: String) {
do{
trydb.run(animals.insert(name <- nameValue))
} catch{
print(error.localizedDescription)
}
}
}
Comments have been added with each line for an explanation. Now, in your search view inside the onAppear() function, check if the searched string already exists in the SQLite database. If NOT, then add the searched text in the SQLite database.
1
2
3
4
5
// add the searched text in SQLite database if NOT exists
let isExists: Bool = DB_Manager().isExists(searchedText: self.searchedText)
Now, we need to show the search history in the main content view when the user clicks on the search bar text field. So, create 2 state wrapper properties in your content view:
1
2
3
4
5
// variable to show search history view
@Statevar showSearchHistoryView: Bool = false
// array of history array
@Statevar history: [Animal] = []
And inside the body, we need to track the live text change of the input field. We have already created a binding variable inside the body of the content view. Change the binding variable inside the content view body to the following:
Now, when the showSearchHistoryView variable is true, we need to display a list of all previously searched strings. So, create a list view under an if condition below the search bar text field:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// show history view only when a variable is true
if(self.showSearchHistoryView) {
// create list view to show all history items
List (self.history) { (model) in
// show history text
HStack {
Image(systemName: "arrow.counterclockwise")
Button(action: {
self.searchedText = model.name
self.gotoSearchPage = true
}, label: {
Text(model.name)
})
}
}
}
This will display a counter clock icon that represents that it is data from history, a button that shows the previously searched string, and which when clicked will move to the search view.
Now, we need to load the data in our history array. So, attach an onAppear() event to your VStack and fetch the data from the SQLite database and save it in the history array.
1
2
3
4
// load data in history models array
.onAppear(perform: {
self.history = DB_Manager().getAnimals()
})
Now, we need to create a function named getAnimals() in our DB_Manager class that will fetch the records from the SQLite database.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// return array of animal models
publicfunc getAnimals() -> [Animal] {
// create empty array
var animalModels: [Animal] = []
// get all animals in descending order
animals = animals.order(id.desc)
// exception handling
do{
// loop through all animals
foranimal in trydb.prepare(animals) {
// create new model in each loop iteration
let animalModel: Animal = Animal()
// set values in model from database
animalModel.id= animal[id]
animalModel.name = animal[name]
// append in new array
animalModels.append(animalModel)
}
} catch{
print(error.localizedDescription)
}
// return array
returnanimalModels
}
Comments have been added with each line for an explanation. If you run the code now, you will be able to view all the searched strings in a list view, upon click it will take you to the search view screen.
At this point, the search bar in Swift UI is completed. But you can go further and add the delete functionality. So user can remove his searched queries.
Delete history
Now, we need a function to delete the string from search history. First, create a button inside your history list after the counter-clock icon and button in your content view:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
... counter-clock icon and button
// show delete button
Spacer()
Button(action: {
// delete history item from SQLite
DB_Manager().deleteAnimal(idValue: model.id)
// refresh the list view
self.history = DB_Manager().getAnimals()
}, label: {
Text("Delete")
.foregroundColor(Color.red)
})// by default, buttons are full width.
// to prevent this, use the following
.buttonStyle(PlainButtonStyle())
Now, we need to create a function named deleteAnimal() in our DB_Manager class that will delete the row from the SQLite database.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// function to delete animal from search history
publicfunc deleteAnimal(idValue: Int64) {
do{
// get animal using ID
let animal: Table = animals.filter(id== idValue)
// run the delete query
trydb.run(animal.delete())
} catch{
print(error.localizedDescription)
}
}
Run the code now, and you will be able to see a delete button at the end of each history row. Upon clicking, it will remove the row from the SQLite database and from the list view as well.
So you have successfully created a search bar in Swift UI along with search history.
You can also learn to create a UICollectionView with a search bar from the following tutorial.