When I click back and forward Buton of browser all of my dynamically created PartialView get disappered - asp.net-core-mvc

I can create multiple Partialviews in my view
Create.cshtml
#model Opto.Models.Recipe
....
<div id="Far" class="tab-pane active card-body">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="row form-group">
<div class="col">
<div class="text-left" dir="ltr">
<partial name="RecipeFarSighted.cshtml" Model="Model.FarSighted" />
</div>
<hr />
<div class="text-center" dir="rtl">
<div id="FarSightedBillsSection">
#*FarSightedBills will be created here by javascript*#
</div>
<a onclick="AddBill('far')" style="cursor:pointer"><img src="~/images/Plus.png" width="25" height="25" /></a>
<br /><br />
#if (!Model.FarSighted.Share)
{
<div class="form-group row form-check">
<label class="form-check-label col">
<input asp-for="FarSighted.Share" type="checkbox"> عدم دریافت عینک
</label>
</div>
}
</div>
</div>
</div>
<br />
</div>
...
#section Scripts{
<script>
var farIndex = 0;
var farRealCount = 0;
function AddBill(type)
{
tag = "<div id='farSightedBill" + farIndex + "' ><a onclick=\"RemovePartial('far'," + farIndex + ")\" style='cursor: pointer'><img src='/images/Minus.png' width='25' height='25' /></a><h4><a onclick=\"$('#farSighted" + farIndex + "').collapse('toggle')\" style='cursor: pointer' data-target='#farSighted" + farIndex + "' id='farBillTitle" + farIndex + "' > عینک دائمی " + (farRealCount + 1) + "</a ></h4 > <br /><div class='collapse' id='farSighted" + farIndex + "'></div></div > ";
$.get('/Glasses/DisplayFarBill?index=' + farIndex +
'&packFactor=' + '#(Model.FarSighted?.PackFactor)' + '&lenseCover=' + '#(Model.FarSighted?.LenseCover)',
function (partial) {
$('#FarSightedBillsSection').append(tag);
$('#farSighted' + farIndex).append(partial);
$('#farSighted' + farIndex).collapse('show');
//aaa(farIndex);
farIndex++;
farRealCount++
});
}
</script>
}
when I click the Back button of the browser and then forward, all my partial views will be disappeared. how can I solve this?
and when I go to submit action method in the controller for validation and there are some errors in it, when it goes back to view there are no parts in it, what should I do?

Firstly,the Back and Forward button is used for navigating through visited Web pages.And it may uses BFCache,it will cache the whole page including jquery(Source code).And the partial view you added will not shown after Back,Forward click is because it is added by jquery.jquery will change the html code,but will not change the source code.When you click Back,Forward button,browser will reload the Source code,and render it to html code.If you want to show the partial view,you can only add them directly like this in your code:
<div class="text-left" dir="ltr">
<partial name="RecipeFarSighted.cshtml" Model="Model.FarSighted" />
</div>

Related

Spring Boot + Thymeleaf: combine filtering and pagination for list

Good evening all,
I'm learning Thymeleaf and web applications in general right now, and for starters, I'm trying to implement a web service with a page where you can view all registered users and filter them.
Since I want some pagination, I have two forms on this page:
a group of buttons linking to the first, previous, next, and last page
a form with various options for filtering, e.g. "username contains" or "min / max age"
My controller looks like this:
#RequestMapping("/users/all")
String showSearchPage(#RequestParam(value="page", required=false, defaultValue = "0") int page,
#CurrentSecurityContext(expression="authentication?.name") String username,
Model model) {
Page<User> userPage = userService.filterUsers(username, "", 0, 100, PageRequest.of(page, 10));
model.addAttribute("userPage", userPage);
model.addAttribute("pageNr", page);
return "users.html";
}
As you can see, I only implemented the buttons yet and always filter for some default values. (The username parameter makes sure that the currently logged in user isn't finding themself in the list.) My button form looks like that:
<form class="button" th:action="#{/users/all}" method="POST">
<button th:disabled="${pageNr == 0}" type="submit"
class="btn btn-primary"
name="page" th:value="0"><<</button>
<button th:disabled="${pageNr == 0}" type="submit"
class="btn btn-primary"
name="page" th:value="${pageNr - 1}"><</button>
<button th:disabled="${pageNr == userPage.getTotalPages - 1}" type="submit"
class="btn btn-primary"
name="page" th:value="${pageNr + 1}">></button>
<button th:disabled="${pageNr == userPage.getTotalPages - 1}" type="submit"
class="btn btn-primary"
name="page" th:value="${userPage.getTotalPages - 1}">>></button>
</form>
So I'm using the request parameter page to only show the requested page.
Now that I'm about to implement the filtering, my first approach would be adding the form to my HTML, and adding some #ModelAttribute FilterForm filterForm to my controller to be able to get the submitted filter values and use them to retrieve the filtered user list. However, when thinking about it, I found the problem that both forms would only submit their own content, and the controller would only get one of both. Therefore, after filtering users, I would inadvertedly revert back to the full user list when changing pages.
What would be the best approach here to make sure that both functions, filtering and pagination, work together properly?
Thanks in advance!
I'd go with HTTP GET method instead of POST. Why so? Reading users is an idempotent and safe operation. The applied filter and page number can be easily bookmarked in that case.
For filters, you can just add more params. Nothing bad about that.
Make it a bit more RESTful. "/users/all" is unnecessary. "/users" should be enough.
#GetMapping("/users")
String showSearchPage(#RequestParam(value="page", required=false, defaultValue = "0") int page,
#RequestParam("minAge") Optional<Integer> minAge,
#RequestParam("maxAge") Optional<Integer> maxAge,
#CurrentSecurityContext(expression="authentication?.name") String username,
Model model) {
// Apply filters too...
Page<User> userPage = userService.filterUsers(username, "", 0, 100, PageRequest.of(page, 10));
model.addAttribute("userPage", userPage);
model.addAttribute("pageNr", page);
model.addAttribute("nextPage", getPageWithFilterUrl(page + 1, minAge, maxAge));
model.addAttribute("previousPage", getPageWithFilterUrl(page - 1, minAge, maxAge));
return "users.html";
}
To preserve filter while moving back and forth:
private String getPageWithFilterUrl(int page, Optional<Integer> minAge, Optional<Integer> maxAge) {
String defaultNextPageUrl = "/users?page=" + page;
String withMinAge = minAge.map(ma -> defaultNextPageUrl + "&minAge=" + ma).orElse(defaultNextPageUrl);
String withMaxAge = maxAge.map(ma -> withMinAge + "&maxAge=" + ma).orElse(withMinAge);
return withMaxAge;
}
I think the answer is not given here yet. I have the same problem now. I am trying in my project with redirectAttributes.addFlashAttribute("searchProductItemDTO", searchProductItemDTO);
But the problem comes when clicking on the Next/Previous buttons - clicking them does not take into account the search criteria.
Here is my total solution:
1) Pay attention here to the JpaSpecificationExecutor<ItemEntity>
#Repository
public interface AllItemsRepository extends
PagingAndSortingRepository<ItemEntity, Long>, JpaSpecificationExecutor<ItemEntity>{
}
2) Pay attention here to the CriteriaBuilder
public class ProductItemSpecification implements Specification<ItemEntity> {
private final SearchProductItemDTO searchProductItemDTO;
private final String type;
public ProductItemSpecification(SearchProductItemDTO searchProductItemDTO, String type) {
this.searchProductItemDTO = searchProductItemDTO;
this.type = type;
}
#Override
public Predicate toPredicate(Root<ItemEntity> root,
CriteriaQuery<?> query,
CriteriaBuilder cb) {
Predicate predicate = cb.conjunction();
predicate.getExpressions().add(cb.equal(root.get("type"), type));
if (searchProductItemDTO.getModel() != null && !searchProductItemDTO.getModel().isBlank()) {
Path<Object> model = root.get("model");
predicate.getExpressions().add(
//!!!!! when we have two relationally connected tables
// cb.and(cb.equal(root.join("model").get("name"), searchProductItemDTO.getModel()));
//when all fields are from the same table ItemEntity:::: the like works case insensitive
cb.and(cb.like(root.get("model").as(String.class), "%" + searchProductItemDTO.getModel() + "%"))
);
}
if (searchProductItemDTO.getMinPrice() != null) {
predicate.getExpressions().add(
cb.and(cb.greaterThanOrEqualTo(root.get("sellingPrice"),
searchProductItemDTO.getMinPrice()))
);
}
if (searchProductItemDTO.getMaxPrice() != null) {
predicate.getExpressions().add(
cb.and(cb.lessThanOrEqualTo(root.get("sellingPrice"),
searchProductItemDTO.getMaxPrice()))
);
}
return predicate;
}
}
3) Pay attention here to the this.allItemsRepository.findAll default usage
//Complicated use
public Page<ComputerViewGeneralModel> getAllComputersPageableAndSearched(
Pageable pageable, SearchProductItemDTO searchProductItemDTO, String type) {
Page<ComputerViewGeneralModel> allComputers = this.allItemsRepository
.findAll(new ProductItemSpecification(searchProductItemDTO, type), pageable)
.map(comp -> this.structMapper
.computerEntityToComputerSalesViewGeneralModel((ComputerEntity) comp));
return allComputers;
}
4) Pay attention here to the redirectAttributes.addFlashAttribute
#Controller
#RequestMapping("/items/all")
public class ViewItemsController {
private final ComputerService computerService;
#GetMapping("/computer")
public String viewAllComputers(Model model,
#Valid SearchProductItemDTO searchProductItemDTO,
#PageableDefault(page = 0,
size = 3,
sort = "sellingPrice",
direction = Sort.Direction.ASC) Pageable pageable,
RedirectAttributes redirectAttributes) {
if (!model.containsAttribute("searchProductItemDTO")) {
model.addAttribute("searchProductItemDTO", searchProductItemDTO);
}
Page<ComputerViewGeneralModel> computers = this.computerService
.getAllComputersPageableAndSearched(pageable, searchProductItemDTO, "computer");
model.addAttribute("computers", computers);
redirectAttributes.addFlashAttribute("searchProductItemDTO", searchProductItemDTO);
return "/viewItems/all-computers";
}
5) Pay attention here to all the search params that we add in the html file, in the 4 sections where pagination navigation
<main>
<div class="container-fluid">
<div class="container">
<h2 class="text-center text-white">Search for offers</h2>
<form
th:method="GET"
th:action="#{/items/all/computer}"
th:object="${searchProductItemDTO}"
class="form-inline"
style="justify-content: center; margin-top: 50px;"
>
<div style="position: relative">
<input
th:field="*{model}"
th:errorclass="is-invalid"
class="form-control mr-sm-2"
style="width: 280px;"
type="search"
placeholder="Model name case Insensitive..."
aria-label="Search"
id="model"
/>
<input
th:field="*{minPrice}"
th:errorclass="is-invalid"
class="form-control mr-sm-2"
style="width: 280px;"
type="search"
placeholder="Min price..."
aria-label="Search"
id="minPrice"
/>
<input
th:field="*{maxPrice}"
th:errorclass="is-invalid"
class="form-control mr-sm-2"
style="width: 280px;"
type="search"
placeholder="Max price..."
aria-label="Search"
id="maxPrice"
/>
</div>
<button class="btn btn-outline-info my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
<h2 class="text-center text-white mt-5 greybg" th:text="#{view_all_computers}">.........All
Computers.......</h2>
<div class="offers row mx-auto d-flex flex-row justify-content-center .row-cols-auto">
<div
th:each="c : ${computers}" th:object="${c}"
class="offer card col-sm-2 col-md-3 col-lg-3 m-2 p-0">
<div class="card-img-top-wrapper" style="height: 20rem">
<img
class="card-img-top"
alt="Computer image"
th:src="*{photoUrl}">
</div>
<div class="card-body pb-1">
<h5 class="card-title"
th:text="' Model: ' + *{model}">
Model name</h5>
</div>
<ul class="offer-details list-group list-group-flush">
<li class="list-group-item">
<div class="card-text"><span th:text="'* ' + *{processor}">Processor</span></div>
<div class="card-text"><span th:text="'* ' + *{videoCard}">Video card</span></div>
<div class="card-text"><span th:text="'* ' + *{ram}">Ram</span></div>
<div class="card-text"><span th:text="'* ' + *{disk}">Disk</span></div>
<div th:if="*{!ssd.isBlank()}" class="card-text"><span th:text="'* ' + *{ssd}">SSD</span></div>
<div th:if="*{!moreInfo.isBlank()}" class="card-text"><span th:text="'* ' + *{moreInfo}">More info</span>
</div>
<div class="card-text"><span th:text="'We sell at: ' + *{sellingPrice} + ' лв'"
style="font-weight: bold">Selling price</span></div>
</li>
</ul>
<div class="card-body">
<div class="row">
<a class="btn btn-link"
th:href="#{/items/all/computer/details/{id} (id=*{itemId})}">Details</a>
<th:block sec:authorize="hasRole('ADMIN') || hasRole('EMPLOYEE_PURCHASES')">
<a class="btn btn-link alert-danger"
th:href="#{/pages/purchases/computers/{id}/edit (id=*{itemId})}">Update</a>
<form th:action="#{/pages/purchases/computers/delete/{id} (id=*{itemId})}"
th:method="delete">
<input type="submit" class="btn btn-link alert-danger" value="Delete"></input>
</form>
</th:block>
</div>
</div>
</div>
</div>
<div class="container-fluid row justify-content-center">
<nav>
<ul class="pagination">
<li class="page-item" th:classappend="${computers.isFirst()} ? 'disabled' : ''">
<a th:unless="${computers.isFirst()}"
class="page-link"
th:href="#{/items/all/computer(size=${computers.getSize()},page=0,model=${searchProductItemDTO.getModel()}, minPrice=${searchProductItemDTO.getMinPrice()},maxPrice=${searchProductItemDTO.getMaxPrice()})}">First</a>
</li>
</ul>
</nav>
<nav>
<ul class="pagination">
<li class="page-item" th:classappend="${computers.hasPrevious() ? '' : 'disabled'}">
<a th:if="${computers.hasPrevious()}"
class="page-link"
th:href="#{/items/all/computer(size=${computers.getSize()},page=${computers.getNumber() - 1},model=${searchProductItemDTO.getModel()}, minPrice=${searchProductItemDTO.getMinPrice()},maxPrice=${searchProductItemDTO.getMaxPrice()})}">Previous</a>
</li>
</ul>
</nav>
<nav>
<ul class="pagination">
<li class="page-item" th:classappend="${computers.hasNext() ? '' : 'disabled'}">
<a th:if="${computers.hasNext()}"
class="page-link"
th:href="#{/items/all/computer(size=${computers.getSize()},page=${computers.getNumber() + 1},model=${searchProductItemDTO.getModel()}, minPrice=${searchProductItemDTO.getMinPrice()},maxPrice=${searchProductItemDTO.getMaxPrice()})}">Next</a>
</li>
</ul>
</nav>
<nav>
<ul class="pagination">
<li class="page-item" th:classappend="${computers.isLast()} ? 'disabled' : ''">
<a th:unless="${computers.isLast()}"
class="page-link"
th:href="#{/items/all/computer(size=${computers.getSize()},page=${computers.getTotalPages()-1},model=${searchProductItemDTO.getModel()},minPrice=${searchProductItemDTO.getMinPrice()},maxPrice=${searchProductItemDTO.getMaxPrice()})}">Last</a>
</li>
</ul>
</nav>`enter code here`
</div>
</div>
</main>

Can't fill_in value because Capybara don't see popup

As I know, when popup/modal opens it is on the top of page where I opened it from, so when try to fill value in it don't see where it need to do that.
Then tried to look inside modal with within. Tried other classes, but same Capybara::ElementNotFound: Unable to find visible css "modal183"
within('modal183') do
fill_in 'ctl00_ContentPlaceHolder1_tbId', :with => '10'
end
Tried also find with xpath, but also nothing
Capybara::ElementNotFound: Unable to find visible xpath "//input[#id='ctl00_ContentPlaceHolder1_tbId']"
<div class="modal183">
<div class="popup_Titlebar" id="PopupHeader">
<div class="TitlebarLeft">
<span id="ctl00_ContentPlaceHolder1_lblTitle">text</span>
</div>
</div>
<div class="popup_Body">
<div class="popup_TextNoTop">
<span id="ctl00_ContentPlaceHolder1_lbl1" class="label-left">text</span>
<input name="ctl00$ContentPlaceHolder1$tbId" type="text" id="ctl00_ContentPlaceHolder1_tbId" class="txtInputDec width100" onFocus="ClearTheTextbox(this, '')" onBlur="FillTheTextbox(this, '')" onkeypress="return onlyNumbers()" />
<span id="ctl00_ContentPlaceHolder1_cmrvIB" style="color:Red;display:none;"><a href='#' class='tooltipCons'><img src='/App_Themes/Default/img/exclamation.png' alt='' /><span>text</span></a></span>
<span id="ctl00_ContentPlaceHolder1_revIB" style="color:Red;display:none;"><a href='#' class='tooltipCons'><img src='/App_Themes/Default/img/exclamation.png' alt='' /><span>text
</span></a></span>
<span id="ctl00_ContentPlaceHolder1_rvTb" style="color:Red;display:none;"><a href='#' class='tooltipCons'><img src='/App_Themes/Default/img/exclamation.png' alt='' /><span>text</span></a></span>
<br />
<span id="ctl00_ContentPlaceHolder1_lbl2" class="label-left">text</span>
<input name="ctl00$ContentPlaceHolder1$tb1Id" type="text" id="ctl00_ContentPlaceHolder1_tb1Id" class="txtInputDec width100 top5" onFocus="ClearTheTextbox(this, '')" onBlur="FillTheTextbox(this, '')" onkeypress="return onlyNumbers()" />
<span id="ctl00_ContentPlaceHolder1_rev1IB" style="color:Red;display:none;"><a href='#' class='tooltipCons'><img src='/App_Themes/Default/img/exclamation.png' alt='' /><span>text
</span></a></span>
<span id="ctl00_ContentPlaceHolder1_rvTb1" style="color:Red;display:none;"><a href='#' class='tooltipCons'><img src='/App_Themes/Default/img/exclamation.png' alt='' /><span>text</span></a></span>
</div>
</div>
<div class="popup_Buttons">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td align="left">
<a onclick="if (!window.event) {this.disabled=true; this.style.color='grey'; var but = document.getElementById('btnCancel'); but.disabled=true; but.style.color='grey';};" id="ctl00_ContentPlaceHolder1_btnOkay" class="cool-button width80 blue" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$ContentPlaceHolder1$btnOkay", "", true, "cons", "", false, true))">text</a>
</td>
<td align="right">
<a id="ctl00_ContentPlaceHolder1_btnCancel" class="cool-button width80 black" href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$btnCancel','')">Atcelt</a>
</td>
</tr>
</table>
</div>
</div>
Updated: Attached part where it looks like be this popup which appear after I press on button. Inspect code shows on this code. I didn't wrote this code, but trying to build automated tests on them :)
<div id="popupparent" style="display: block; height: 1e+06px; left: 0px; top: 0px;">
<script language="javascript" type="text/javascript">
function resizeIframe(obj) {
var h = "innerHeight" in window ? window.innerHeight : document.documentElement.offsetHeight;
var w = "innerWidth" in window ? window.innerWidth : document.documentElement.offsetWidth;
var doc;
if (obj.contentDocument) {
doc = obj.contentDocument;
} else if (obj.contentWindow) {
doc = obj.contentWindow.document;
} else {
return;
}
var childHeight = doc.body.scrollHeight;
var childWidth = doc.body.scrollWidth;
obj.style.height = childHeight + 'px';
var ver = getInternetExplorerVersion();
var parent = document.getElementById('termsofuse');
if (ver > -1) {
parent.style.marginTop = ((h - childHeight) / 2) - 64 + 'px';
} else {
parent.style.top = ((h - childHeight) / 2) - 64 + 'px';
}
parent.style.left = ((w - childWidth) / 2) + 'px';
parent.style.display = "block";
parent.style.visibility = "visible";
}
<div id="termsofuse" style="left: 1081px; top: 246.5px; display: block; visibility: visible;">
<iframe id="frameeditexpanse" frameborder="0" src="PopDailyCons.aspx?e=c0lEPUMwMDEwMDA3MDQmYUlEPUEwMDQ3ODIxNzAmZGF5PTImY3VyRGF0ZT0yMDE4LjA0JmN1clVzZXI9MTYwJnNvdXJjZT1hdGs=" scrolling="no" marginheight="0" marginwidth="0" class="termsOfUseFrame" style="height: 185px;"> </iframe>
<div class="popup_Buttons" style="display: none">
<input id="btnOk" value="Done" type="button">
<input id="btnCancel" value="Cancel" type="button" onclick="hideusertermwindow()">
Your within call doesn't work because you need to pass it a CSS selector. You're passing modal183 which would look for a <modal183> element, when what you really want is .modal183 to look for an element with the class modal183.
From your description it's tough to tell exactly what you're doing but it sounds like maybe you're talking about a popup window (new browser window) opened on top of the current tab. If that is the case then you'd need to swap windows in order to interact with it, along the lines of
new_win = window_opened_by do
# whatever action in the original window causes the popup window to open
click_button 'blah'
end
within_window(new_win) do
fill_in 'ctl00_ContentPlaceHolder1_tbId', :with => '10'
end

Loading a partial view into a DIV element dynamically is replacing the entire DOM vs the element

Within a view I am trying to load a partial view from the controller. I am using the Ajax.ActionLink method to make this call
#Ajax.ActionLink("Involved Entities/Resources",
"GetNarratives",
new { id = 4 },
new AjaxOptions { HttpMethod = "GET",
UpdateTargetId = "narrContainer" })
Further down in the page I have a div element with the id of narrContainer
<div id="narratives" class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><a data-toggle="collapse" href="#collapseNarrative">Narratives [ #Model.AssociatedNarrative.Count() ]</a></h4>
</div>
<div id="collapseNarrative" class="panel-collapse collapse">
<div class="panel-body">
<div id="narrContainer"></div>
</div>
</div>
</div>
</div>
</div>
The controller has the following code:
public PartialViewResult GetNFIRNarratives(string id)
{
//Get Narratives
fauxModel fm = new fauxtModel();
List<Narrative> narr = new List<Narrative>();
narr = fm.GenerateMockBaseNarratives(4);
return PartialView("_myAssociatedNarrative", narr);
}
The partial view contains fields for the collection:
<!-- Assocaited Narrative-->
#for (int i = 0; i < #Model.Count(); i++)
{
<div class="col-md-12">
<p><strong>Date Entered</strong> #Html.DisplayFor(x => x[i].DateEntered)</p>
</div>
if (!string.IsNullOrWhiteSpace(#Model[i].Title))
{
<div class="col-md-12">
<p><strong>Narrative Title</strong> #Html.DisplayFor(x => x[i].Title) </p>
</div>
}
<div class="col-md-12">
<p>#Html.DisplayFor(x => x[i].NarrativeText)</p>
<hr />
</div>
}
Within the base layout page I have added reference to the unobtrusive-ajax script as
<script src="#Url.Content("~/js/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
And I have confirmed that the key is enabled in the web.config file.
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
When I click on the link to load the narratives the code executes but it does not load the partial in the div element. Instead it is replacing the current view the partial. What I am missing that is causing the partial to be loaded /replacing the current document and what do I need to change to get the partial to render only within the specified div element?
After working through the Post Event more I discovered that the #Ajax.Action was not posting as an AJAX call. This was the result of the jquery-unobtrusive-ajax.js file being outdated and containing deprecated jquery functions (.live()) .
I updated the files through NuGet using
Install-Package Microsoft.jQuery.Unobtrusive.Ajax
and the actions are now working correctly.

Kendo mobile view parameters

I have a a basic kendo view and am wondering if there is a way to access the view.params without using the data-show or data-init to run a js OR if i do use the current functon call on data-show how can i dynamically populate the data elements of my EDIT button?
<!-- eventDetail view -------------------------------------------------------------------------------------------------->
<div data-role="view" id="view-eventDetail" data-show="getEventDetailData" data-title="eventDetail">
<header data-role="header">
<div data-role="navbar">
<span data-role="view-title"></span>
<a data-align="left" data-role="button" class="nav-button" href="#view-myEvents">Back</a>
<a data-align="right" data-role="button" class="nav-button" data-click="showEventUpdate" data-event_id="view.params.event_id" data-user_id="view.params.user_id">Edit</a>
</div>
</header>
<div id="eventDetail"></div>
</div>
The best method i have found so far (access view parameters in view) is to use the Kendo ViewModel method - MVVM - and the template - pulling in the view.params from a querystring click:
<a data-role="button" href="#view-Home?userID=2&userType=1&trainerID=2">
Then call a script via the data-show or data-init method of the view and bind the viewModel:
<!-- =========================================================================================== Home page -->
<div data-role="view" id="view-Home" data-title="Home" data-show="checkAuth" data-model="home_viewModel" >
<div id="homeWrapper">
<div id="myTrainerInfo" data-template="myTrainerIcon-template" data-bind="source: user_info" ></div>
</div>
<!-- ========================================================================================= Home script -->
<script>
//init the viewmodel
var home_viewModel = kendo.observable({
user_info: []
});
function checkAuth(e) {
var userID = e.view.params.userID;
var userType = e.view.params.userType;
var trainerID = e.view.params.trainerID;
var userData = {userID:userID,userType:userType,trainerID:trainerID};
//set the viewmodel data
home_viewModel.set("user_info", userData);
}
</script>
The vars can then be accessed via ${var_name} or via HTML data-bind="value: var_name":
<!-- ============================================================================== myTrainerIcon template -->
<script id="myTrainerIcon-template" type="text/x-kendo-template">
<div id="myTrainerIcon" class="homePageIcons">
<a data-role="button" href="\\#view-trainerDetail?user_id=${userID}&trainer_id=${trainerID}">
<img src = "styles/icons/myTrainerICON.png" alt="myTrainer" />
</a>
<div class = "icon-text" >myTrainer</div>
</div>
<div>TrainerID: <input name="edit_id" id="edit_id" data-min="true" class="k-input" data-bind="value: trainerID" type="text" /></div>
</script>
Im sure there is a different way to do this but so far nothing i have discovered on my own..

Replacing the slide image with another image in a slideshow(Jquery Cycle) using Javascript

I have 10 images that are displayed as a slideshow using the Jquery Cycle plugin.
At a time 4 images are displayed . When the user clicks the next button the next 4 images are displayed.
Under each image there is a dropdown. When I select an item in the dropdown I want to change the image to some other image depending on the item the user has selected in the dropdowm.
I also need to change the 'href' of the image when the user selects another item in the dropdown.
When the user selects an item in the dropdown I using the javascript code given below to change the image and other details
Javascript Code
document.getElementById('prodLink' + productId).href = "productDetails.aspx?id=" + productAttributeValueId;
document.getElementById('prodImageLink' + productId).href = "productDetails.aspx?id=" + productAttributeValueId;
document.getElementById('prodImage' + productId).src = "ProductImages/" + productImage;
document.getElementById('prodImage' + productId).className=document.getElementById('prodImage' + productId).className;
document.getElementById('prodNameLink' + productId).href = "productDetails.aspx?id=" + productAttributeValueId;
document.getElementById('productPrice' + productId).innerHTML = productPrice;
document.getElementById('prodAttribute' + productId).innerHTML = attributeValue;
The HTML Code
<div class="cycle-slideshow" data-cycle-fx="scrollHorz" data-cycle-timeout="0"
data-cycle-slides="> ul" data-cycle-prev="div.pagers a.latest_prev" data-cycle-next=
"div.pagers a.latest_nxt">
<ul class="product_show">
<li class="column">
<div class="img">
<div class="hover_over">
<a class="link" href="#">link</a> <a class="cart" href="#">cart</a>
</div><a href="#"><img src="images/photos/4c_pic8.jpg" width="218" height="207"
alt="" /></a>
</div><a href="#" style="line-height:14px;">Product 1,<br />
1 Kg Pouch<br /></a> <span class="ourPrice">Our Price: $121.20</span><span class=
"saveText"><br /></span>
<div class="dropdowndiv">
<select name="search_category1" class="default" tabindex="1" style=
"color: #333333;">
<option value="">
Pack size
</option>
<option value="amazed">
Amazed
</option>
</select>
</div><br />
<br />
<label for="textfield">Qty</label> <input type="text" name="textfield" id=
"textfield" class="carttextbox" /> <img src="images/img/but_addtocart.png"
alt="" width="72" height="16" align="absmiddle" /><br />
<br />
</li>
</ul>
Here is the modified working javascript code that changes the image(and some other information) in a Jquery Cycle2 slideshow
I added $('.cycle-slideshow').cycle('destroy'); before changing any information
After that I change all the required information
Then I call $('.cycle-slideshow').cycle(); to recreate the slideshow
$('.cycle-slideshow').cycle('destroy');
document.getElementById('prodLink' + productId).href = "productDetails.aspx?id=" + productAttributeValueId;
document.getElementById('prodImageLink' + productId).href = "productDetails.aspx?id=" + productAttributeValueId;
document.getElementById('prodImage' + productId).src = "ProductImages/" + productImage;
document.getElementById('prodImage' + productId).className=document.getElementById('prodImage' + productId).className;
document.getElementById('prodNameLink' + productId).href = "productDetails.aspx?id=" + productAttributeValueId;
document.getElementById('productPrice' + productId).innerHTML = productPrice;
document.getElementById('prodAttribute' + productId).innerHTML = attributeValue;
$('.cycle-slideshow').cycle();

Resources