드롭다운 메뉴를 만들기 위해 Ajax와 JSON을 사용하는 방법은?
다음은 OpenCart에서 다른 레벨의 카테고리 메뉴를 표시할 때 사용한 코드입니다.작동하지만 클릭할 때마다 점점 더 많이 생성됩니다.XHR finished loading: POST
그리고.XHR finished loading: GET
s는 때때로 다음을 클릭하여 페이지를 클릭합니다.
<script type="text/javascript">
_url = '';
$(document).ready(function(){
$('#mnav a').on('click', function() {
var cat = $(this).attr('id');
_url = '&category_id=' + cat;
$.post('index.php?route=test/category/child' + _url,
function(data) {
if(data.length>10){
$('#mnav #sub').remove();
$(data).insertAfter($('#mnav #' + cat));
}
});
});
});
$.ajaxPrefilter(function( options, original_Options, jqXHR ) {
options.async = true;
});
</script>
HTML 코드:
<div id="mnav" class="list-group">
<?php foreach ($categories as $category) { ?>
<a id="<?php echo $category['category_id']; ?>" class="list-group-item active"><?php echo $category['name']; ?></a>
<?php } ?>
</div>
컨트롤러 코드:
<?php
class ControllerTestCategory extends Controller {
public function index() {
if (isset($this->request->get['path'])) {
$parts = explode('_', (string)$this->request->get['path']);
} else {
$parts = array();
}
$data['category_id'] = 0;
if (isset($parts[0])) {
$data['category_id'] = $parts[0];
} else {
$data['category_id'] = 0;
}
if (isset($parts[1])) {
$data['child_id'] = $parts[1];
} else {
$data['child_id'] = 0;
}
$this->load->model('catalog/cat');
$data['categories'] = array();
$categories = $this->model_catalog_cat->getCategories(0);
foreach ($categories as $category) {
$children_data = array();
$filter_data = array(
'filter_category_id' => $category['category_id'],
'filter_sub_category' => true
);
$data['categories'][] = array(
'category_id' => $category['category_id'],
'name' => $category['name'],
'children' => $category['children'],
'products' => $category['products'],
'href' => $this->url->link('product/category', 'path=' . $category['category_id'])
);
}
$this->response->setOutput($this->load->view('test/category', $data));
}
public function child() {
if (isset($this->request->get['category_id'])) {
$this->load->model('catalog/cat');
$data['categories'] = array();
$categories = $this->model_catalog_cat->getCategories($this->request->get['category_id']);
$data['x'] = '<div id="sub">';
foreach ($categories as $category) {
$data['x'] .= '<li>' . $category['name'] . '</li>';
}
$data['x'] .= '</div>';
} else {
$data['x'] = 'NA';
}
$this->response->setOutput($this->load->view('test/category', $data));
}
}
SQL 코드:
public function getCategories($parent_id = 0) {
$sql = "SELECT c.category_id, c.parent_id, cd.name,
(SELECT COUNT(DISTINCT ch.category_id) from category ch where ch.parent_id = c.category_id and cd.language_id = '" . (int)$this->config->get('config_language_id') . "') as children";
$sql .= " , (SELECT COUNT(DISTINCT p.product_id)
FROM product p
LEFT JOIN product_description pd ON (p.product_id = pd.product_id)
LEFT JOIN product_to_category p2c ON (p2c.product_id = p.product_id)
LEFT JOIN category_path cp ON (cp.category_id = p2c.category_id)
WHERE
pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND
p.status = '1' AND
p.date_available <= NOW()) AS items";
$sql .= " FROM category c LEFT JOIN category_description cd ON (c.category_id = cd.category_id) WHERE c.parent_id = '" . (int)$parent_id . "' AND cd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND c.status = '1' ORDER BY c.sort_order, LCASE(cd.name)";
$query = $this->db->query($sql);
return $query->rows;
}
저는 이 과목들을 거의 알지 못하기 때문에 필요한 모든 자바스크립트, jQuery, JSON 코드를 제공하여 저를 도와주시면 대단히 감사하겠습니다 :-(
게시 요청 결과를 자바스크립트 배열에 저장하여 재사용할 수 있으므로 다음을 참조하시기 바랍니다.
var cachedObj = [];
$(document).ready(function(){
$('#mnav a').on('click', function() {
var cat = $(this).attr('id');
_url = '&category_id=' + cat;
getData(cat, _url); //<-- Get data from ajax or cache
});
});
//This function replaces the $.post call (just for example)
function dummyPost(id, url){
//url should be used to make the post call
var data = "<span class='sub'>Test " + id + "</span>";
return data;
}
function getData(id, url){
//Try to get data from cache
var data;
if(cachedObj[url]) {
data = cachedObj[url];
console.log("Data retrived from cache");
}
else {
data = dummyPost(id, url);
cachedObj[url] = data;
console.log("Data retrived from post");
}
$('#mnav .sub').remove();
//$(data).insertAfter($('#mnav #' + id));
$('#mnav #' + id).append($(data));
}
.sub{
color: red;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mnav" class="list-group">
<a id="1" class="list-group-item active">One</a>
<a id="2" class="list-group-item active">Two</a>
<a id="3" class="list-group-item active">Three</a>
</div>
제가 해봤습니다.dummyPost
post request를 하기 위해 수정해야 하는 기능.
예제의 로그에서 볼 수 있듯이 링크를 처음 클릭하면 "post"와 함께 하위 메뉴를 검색하고, 그 다음에는 캐시된 배열에서 데이터를 가져옵니다.cachedObj
.
도움이 되길 바랍니다.안녕.
업데이트: 코드에 적용되는 내용은 다음과 같습니다.
<script type="text/javascript">
var cachedObj = []; //<-- Add an array to cache submenus
//Add a function to retrieves data from cache or REST
function getData(url){
//Try to get data from cache
if(cachedObj[url]) {
console.log("Data retrived from cache");
}
else {
$.ajax({
type: 'GET',
url: 'index.php?route=test%2Fcategory%2Fchild' + url,
success: function(data) {
cachedObj[url] = data;
console.log("Data retrived from post");
}),
async:false
});
}
return cachedObj[url];
}
$(document).ready(function(){
$('#mnav a').on('click', function() {
var cat = $(this).attr('id');
var url = '&category_id=' + cat;
var data = getData(url); //<-- Call the new function to get data
if(data.length>10){
$('#mnav #sub').remove();
$(data).insertAfter($('#mnav #' + cat));
}
});
});
</script>
테스트를 할 수가 없어서 오류가 있을 수 있습니다.
문제는 앵커 태그의 기본 작업을 방지하지 못하고 있다는 점일 수 있습니다.추가해 보기event.preventDefault
. 이렇게 하면 브라우저가 실행됩니다.POST
요청이 아닌GET
하나.
게다가 이벤트를 새로 추가하는 경우 요소가 아닌 문서에 바인딩하는 것이 가장 좋습니다.#mnav a
아약스를 통한 요소.
$(document).ready( function() {
$(document).on('click', '#mnav a', function( event ) {
event.preventDefault();
// some code
});
});
코드를 작성하기 전에 클라이언트와 서버가 통신하기를 원하는 방법에 대해 전략을 세워야 할 것 같습니다.
저는 당신의 문제에 대해 이해합니다. "메뉴는 클릭할 때마다 ajax 요청을 생성하는데, 저는 그것을 원하지 않습니다."
하지만 이것이 코드를 만든 방법입니다. jQuery에 의해 설정된 메뉴의 on click handler는$.post()
불러들입니다.
다른 방법은 메뉴를 채우기 위해 필요한 모든 데이터를 클라이언트에게 전송하는 것입니다.그런 다음 메뉴를 클릭할 때마다 ajax 요청을 보내는 대신 이미 메모리에 있는 데이터에서 끌어옵니다.
제가 생각할 수 있는 몇 가지 방법이 있습니다.어떤 전략을 선택하느냐는 시스템에 대한 편안함 및/또는 통제력, 페이지 속도에 대한 우선순위에 따라 달라집니다.
- 서버가 이 데이터를 준비하도록 하고 데이터를 즉시 사용할 수 있도록 서버측 템플릿에 기록합니다.
<script><?php echo 'var menuData = '.json_encode($my_data).'; ?></script>
. 이것이 가장 빠른 옵션입니다. - 기존 ajax URL을 사용하지만 페이지가 로드되면 일련의 ajax 요청을 실행합니다.옵션 1에서와 같이 모든 결과를 일부 중앙 데이터 개체로 보냅니다.모든 데이터가 반환되면 메뉴가 작동합니다.여기서의 장점은 서버 사이드 코드를 변경할 필요가 없다는 것이지만, 많은 통화가 시간이 걸릴 것입니다.
- 한 번에 모든 메뉴 데이터를 반환할 수 있는 새로운 ajax URL을 만듭니다.옵션 2보다는 빠르겠지만 서버 api 작업을 해야 합니다.
저는 아약스 추진 프로젝트에서 이 문제에 직면했습니다.제 해결책이 도움이 되기를 바랍니다.이렇게 하면 더 많은 호출이 생성되지 않을 수 있습니다.
// DOM ready
$(function() {
$(document).off('click', '#mnav a').on('click', '#mnav a', function(e){
e.preventDefault();
// your stuff here
});
});
이 단계를 수행하면 됩니다.
javascript로 드롭다운 만들기:
function myFunction(){
var port_button = document.getElementById("port").value;
if(port_button == 0){
var newhref;
var newhrefid;
var name = ["jquery ajax", "dropdown menu", "db"];
var links = ["api.jquery.com/jquery.ajax/", "www.w3schools.com/howto/howto_js_dropdown.asp", "www.w3schools.com/php/php_ajax_database.asp"];
var div=document.getElementById("myDropdown");
for(var i = 0; i<3; i++){
newhref= document.createElement("a");
newhref.href="http://"+links[i];
newhref.innerHTML= name[i];
newhrefid = "idhr_"+i;
newhref.setAttribute('id', newhrefid );
div.appendChild(newhref);
}
document.getElementById("myDropdown").classList.toggle("show");
document.getElementById("port").value = "2";
}
else if(port_button == 1){
document.getElementById("myDropdown").classList.toggle("show");
document.getElementById("port").value = "2";
}
else{
document.getElementById("myDropdown").classList.toggle("hide");
document.getElementById("port").value = "1";
}
}
function filterFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
div = document.getElementById("myDropdown");
a = div.getElementsByTagName("a");
for (i = 0; i < a.length; i++) {
if (a[i].innerHTML.toUpperCase().indexOf(filter) > -1) {
a[i].style.display = "";
} else {
a[i].style.display = "none";
}
}
}
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #3e8e41;
}
#myInput {
border-box: box-sizing;
background-image: url('searchicon.png');
background-position: 14px 12px;
background-repeat: no-repeat;
font-size: 16px;
padding: 14px 20px 12px 45px;
border: none;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f6f6f6;
min-width: 230px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #ddd}
.show {display:block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Dropdown</button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()">
</div>
</div>
<input type="hidden" id = "port" value = "0">
'입력', 'p', 'a' 등의 요소 드롭다운을 만들 수 있습니다.
특정 ID를 선택하려면 이 html을 코드에 추가합니다.
<form>
<select id = "name_of_user" name="users" onchange="showUser(this.value)">
<option value="">Select a person:</option>
<option value="1">Peter Griffin</option>
<option value="2">Lois Griffin</option>
<option value="3">Joseph Swanson</option>
<option value="4">Glenn Quagmire</option>
</select>
</form>
데이터베이스 데이터를 입력하려면 다음 코드에 가입하십시오.
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT id, name FROM user";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
$option = "";
while($row = $result->fetch_assoc()) {
$option .= '<option value = "'.$row["id"].'">'.ech$row["name"].'</option>';
}
}
$conn->close();
?>
<form>
<select id = "name_of_user" name="users" onchange="showUser(this.value)">
<?php echo $option; ?>
</select>
</form>
이제 드롭 메뉴 코드에 AJAX를 생성하고 가입해야 합니다.
function myFunction(){
var port_button = document.getElementById("port").value;
if(port_button == 0){
var newhref;
var newhrefid;
var div=document.getElementById("myDropdown");
var val_1 = document.getElementById("name_of_user");//If you want to do a where select.
$.ajax({
url: 'test.php',
type: 'POST',
datatype: 'Json',
data: {'q': val_1},
success: function (response) {
var newhref;
var newhrefid;
var div=document.getElementById("myDropdown");
for(var i = 0; i<response.nunber_of_rows; i++){
newhref= document.createElement("a");
newhref.href= response.tabel[i];
newhref.innerHTML= response.tabel[i];
newhrefid = "idhr_"+i;
newhref.setAttribute('id', newhrefid );
div.appendChild(newhref);
}
}
});
document.getElementById("myDropdown").classList.toggle("show");
else if(port_button == 1){
document.getElementById("myDropdown").classList.toggle("show");
document.getElementById("port").value = "2";
}
else{
document.getElementById("myDropdown").classList.toggle("hide");
document.getElementById("port").value = "1";
}
}
데이터베이스에 연결하려면 php가 필요합니다.
<?php
$q = intval($_POST['q']);
$error_state = "";
$con = mysqli_connect('localhost','peter','abc123','my_db');
if (!$con) {
die('Could not connect: ' . mysqli_error($con));
}
mysqli_select_db($con,"ajax_demo");
$sql="SELECT links FROM user WHERE id = '".$q."'";
$result = mysqli_query($con,$sql);
$i = 0;
while($row = mysqli_fetch_array($result)) {
$tabel[$i] = array($row['link']);
$i++;
}
$nunber_of_rows=$i;
mysqli_close($con);
echo json_encode (array(
'tabel'=>$tabel,
'nunber_of_rows'=>$nunber_of_rows
));
?>
제 예제의 출처는 스니펫 예제의 링크에 있습니다.
의심할 여지 없이, 그냥 제 도움을 요청하세요.
자바스크립트 코드 쪽에 문제가 있는 것 같습니다.나는 당신의 PHP와 DB 관련 코드가 제대로 결과를 던지고 있다고 가정합니다.여기서 ajax 메뉴 로더 플러그인을 다운로드하는 것이 더 나은 해결책입니다.
당신은 파일에 결과물을 던지도록 당신의 PHP 코드를 설정할 수 있습니다.HTML 구조를 따라야 할 수도 있고 CSS를 새로운 클래스 이름으로 업데이트하여 스타일을 적용할 수 있습니다.당신의 문제를 해결하는 것이 더 빠르기를 바랍니다.
언급URL : https://stackoverflow.com/questions/43827637/how-to-use-ajax-and-json-for-making-dropdown-menu
'programing' 카테고리의 다른 글
왜 '익명'이스프링 시큐리티에서 인증된 사용자? (0) | 2023.11.05 |
---|---|
C#에서 단일 Oracle 명령어로 여러 쿼리 실행 (0) | 2023.11.05 |
Powershell Console에서 여러 줄 문자열을 할당하는 방법 (0) | 2023.11.05 |
C에서 printf() 함수의 반환 값 (0) | 2023.10.31 |
ASP.NET에서 페이지 캐시 지우기 (0) | 2023.10.31 |