Creed1234, ну конечно нет, это вообще не связанные куски кода выполняющиеся на разных платформах и в разные моменты времени. Приведенный вами код это код шаблона, этот шаблон обрабатывается на сервере и заполняется данными только при первичной загрузке. Это ж php, он на сервере выполняется, к клиенту никакого отношения не имеет, только данные отдаёт и всё,
Вы либо реализуете обновление данных с перезагрузкой страницы, либо на клиенте дублируете обработку шаблона при получении данных, либо просите сервер прислать вам не данные а конкретно вот этот вот шаблон только с новыми данными
Creed1234, "После ajax я получаю обновленный $products и снова его перебираю" - нет, в ответ на запрос к products/sort вы просто получаете объект с данными и нигде его не перебираете. По крайней мере у вас в коде так: вы говорите "снова его перебираю", но я вижу только $("#index").html(res), это же не перебор
Creed1234, ну вот, прекрасно, значит данные вам приходят и вы их можете вывести на страницу. Если нужно чтоб вёрстка была такая же как в исходной странице, то выводите данные на страницу в том же шаблоне который вы привели в начале вопроса
Creed1234, ну во первых вы уже видите наверное что typeof res === object, а это не очень хорошо, потому что метод .html() принимает на вход строку, а не объект. Можете например сделать так: .html(JSON.stringify(res)), или в .ajax укажите dataType: 'html', тогда вам по идее в res строка придёт.