Форма Preventdefault не работает, перенаправление на URL-адрес публикации - PullRequest
0 голосов
/ 06 января 2019

Я работаю над приложением Spring Boot. У меня есть любимая кнопка, в которой изображение кнопки изменяется в зависимости от того, добавил ли пользователь элемент в избранное.

Изначально я работал, принимая запрос на публикацию формы, обновляя БД и отправляя перенаправление обратно в Referer, но это каждый раз перезагружало страницу, поэтому я подумал, что попробую использовать jQuery Ajax.

Controller.java:

//     //Favorite/Unfavorite existing recipes
//    @RequestMapping(value = "/recipes/{id}/favorite", method = RequestMethod.POST)
//    public String favoriteRecipe(@PathVariable Long id, Model model, HttpServletRequest request, Authentication
//            authentication) {
//
//        User user = userService.findByUsername(authentication.getName());
//        model.addAttribute("user", user);
//        Recipe recipe = recipeService.findById(id);
//
//        userService.toggleFavorite(user, recipe);
//
//        userService.save(user);
//
//        return "redirect:" + request.getHeader("Referer");
//    }

    // Favorite/Unfavorite existing recipes
    @PostMapping("/recipes/{id}/favorite")
    @ResponseStatus(value = HttpStatus.OK)
    public void favoriteRecipe(@PathVariable("id") Long id, Model model, Authentication authentication) {
        User user = userService.findByUsername(authentication.getName());
        //model.addAttribute("user", user);
        Recipe recipe = recipeService.findById(id);

        userService.toggleFavorite(user, recipe);

        userService.save(user);

        //return new ResponseEntity<>(HttpStatus.OK);
    }

index.html:

<a th:href="@{|/details/${recipe.id}|}">
   <div class="grid-70">
     <p>
       <form id="test" th:action="@{|/recipes/${recipe.id}/favorite|}" method="post" style="display:inline">
          <button type="submit" id="favorite-button-index">
             <img th:src="${recipe.userFavorites.contains(#authentication.name)} ? @{/assets/images/favorited.svg} : @{/assets/images/favorite.svg}"
                                         style="height: 12px;">
           </button>
       </form>
       <span th:text="${recipe.name}"> </span>

      </p>
    </div>
 </a>

app.js:

$('#test').submit(function (e) {
    e.preventDefault()
    $('#favorite-button-detail').submit(function (e) {
        e.preventDefault()
        var recipeID = [[${recipe.id}]];
        var url = "/recipes/" + recipeID + "/favorite";

        $.post(url, function(data) {
            alert(data)
        });
    })
})

Так я пытался реализовать в своем app.js. Я подтвердил, что данные обновляются в БД, но я не могу остановить перенаправление на URL-адрес POST. Проблема, кажется, исходит от th: action в форме.

Я просмотрел много других вопросов / примеров по этому вопросу и не смог понять, почему это происходит. Я пытался предотвратить, вернуть false, завернуть в $ (документ) .ready ().

Любая помощь будет принята с благодарностью. Спасибо!

Ответы [ 2 ]

0 голосов
/ 06 января 2019

В дополнение к ответу Роко вам все еще нужно найти решение для обновления пользовательского интерфейса, чтобы изменить изображение кнопки без обновления всей страницы, поскольку вы используете серверный механизм рендеринга шаблонов. Я предлагаю вам просто изменить изображение кнопки после успешного ответа, например:

$('#test').on("submit", function (e) {
    e.preventDefault();
    $.post(this.action, function(data) {
        console.log(data);
        var imageUrl = (data.favorited)?'/assets/images/favorited.svg':'/assets/images/favorite.svg'; 
        $('#favorite-button-index>img').attr('src', imageUrl);
    });
};

Также в этом случае, чтобы заставить data.favorited работать, вы должны вернуть данные о том, что пользователь имеет избранное или нет, из метода пружинного контроллера. Вот пример, который возвращает данные JSON, так что вы можете легко использовать в JavaScript:

@PostMapping("/recipes/{id}/favorite")
@ResponseBody
public Map<String, Object> favoriteRecipe(@PathVariable("id") Long id, Authentication authentication) {
    User user = userService.findByUsername(authentication.getName());

    Recipe recipe = recipeService.findById(id);
    userService.toggleFavorite(user, recipe);

    userService.save(user);

    boolean hasFavorite = recipe.userFavorites.contains(authentication.getName());

    Map<String, Object> resultJson = new HashMap<>();
    resultJson.put("favorited", hasFavorite);

    return resultJson;
}
0 голосов
/ 06 января 2019

Не хорошо иметь два вложенных представления. И я не уверен, в чем заключается идея упаковки [[${recipe.id}]] в двойные массивы ... ??

Попробуйте с:

$('#test').on("submit", function (e) {
    e.preventDefault();
    $.post(this.action, function(data) {
        console.log(data);
    });
});

, где this.action - фактическое действие формы значение атрибута @{|/recipes/${recipe.id}/favorite|} И вам больше не нужны кнопки JS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...