I want to retrieve the html attribute of a link and apply to a modal button - hyperlink

I have a list of links and a modal that pops up on click. All i want to achieve is whenever i click on any of the links, retrieve the html attribute of that link and apply to the modal button.
<body x-data="{ extModal : false }">
<ul>
<li><a #click="extModal = !extModal" href="http://examplelink-1.com"></a></li>
<li><a #click="extModal = !extModal" href="http://examplelink-2.com"></a></li>
<li><a #click="extModal = !extModal" href="http://examplelink-3.com"></a></li>
</ul>
<div x-show="extModal">
<h2>External Link Alert</h2>
<p>Are you sure you want to leave this site?</p>
<button #click="extModal = false">No</button>
<!-- Dynamic link update -->
Yes
</div>
</body>

Hi and welcome #demeyo.
I am currently on my phone and can not test it, but I will try to explain how you could simply achieve what you want.
Create a reactive data property (f.e. "activeLink").
Bind that property to your href attribute.
Update that property on click by accessing the target element.
That could look like follows:
<body x-data="{ extModal : false, activeLink: '' }">
<ul>
<li><a #click="extModal = !extModal; activeLink = $event.target.getAttribute('href')" href="http://examplelink-1.com"></a></li>
<li><a #click="extModal = !extModal; activeLink = $event.target.getAttribute('href')" href="http://examplelink-2.com"></a></li>
<li><a #click="extModal = !extModal; activeLink = $event.target.getAttribute('href')" href="http://examplelink-3.com"></a></li>
</ul>
<div x-show="extModal">
<h2>External Link Alert</h2>
<p>Are you sure you want to leave this site?</p>
<button #click="extModal = false">No</button>
<!-- Dynamic link update -->
<a :href="activeLink" #click="extModal = false" target="_blank">Yes</a>
</div>
</body>
Hint: You could use the x-for directive to loop over your links and render them.

Related

Get text of parent dt in Description List

I have a JQuery Mobile popup (an unordered list) embedded in a description list:
<dl data-role="listview" data-inset="true" data-theme="d" id="sortable">
<dt class="ui-bar ui-bar-b ui-corner-all">Group One</dt>
<dd class="ui-bar ui-bar-a ui-corner-all ui-btn-icon-left ui-icon-bars">
<div class="divMain">
<div class="divQuestion">
<textarea name="strQuestion-q1" id="strQuestion-q1" placeholder="Enter Question Number 1" style="margin:0px;"></textarea>
</div>
<div class="divCategory">
<a class="ui-btn ui-corner-all ui-shadow ui-btn-inline" href="#popupMenu-q1" data-rel="popup" data-transition="slideup">Select Category</a>
<div id="popupMenu-q1" data-role="popup" data-theme="b">
<ul style="min-width: 210px;" data-role="listview" data-inset="true">
<li data-role="list-divider">Choose the scoring category</li>
<li><a name="strCategory-o1-q1" href="javascript:void(0);" onclick="selectCategory(this);">Category 1</a></li>
<li><a name="strCategory-o2-q1" href="javascript:void(0);" onclick="selectCategory(this);">Category 2</a></li>
<li><a name="strCategory-o3-q1" href="javascript:void(0);" onclick="selectCategory(this);">Category 3</a></li>
</ul>
</div>
</div>
</div>
</dd>
</dl>
I want the function selectCategory() to get the text of the parent dt (in this case "Group One"). I've tried both of the following with no success:
$('#strCategory-o1-q1').parent().prev('dt').text();
$('#strCategory-o1-q1').closest('dd').prev('dt').text();
Any suggestions?
The problem is that when jQM initializes the popup, it moves it from the current DOM position into a popup container at the top level. So the DD is no longer its ancestor.
One thing you could do is add a click handler to the button that launches the popup and get the text there. Then you could put the text in a global variable or a data-attribute within the popup.
Given this markup:
<a id="btnPopup" class="ui-btn ui-corner-all ui-shadow ui-btn-inline" href="#popupMenu-q1" data-rel="popup" data-transition="slideup">Select Category</a>
<div id="popupMenu-q1" data-role="popup" data-theme="b">
<ul style="min-width: 210px;" data-role="listview" data-inset="true">
<li data-role="list-divider">Choose the scoring category</li>
<li><a name="strCategory-o1-q1" href="#">Category 1</a></li>
<li><a name="strCategory-o2-q1" href="#">Category 2</a></li>
<li><a name="strCategory-o3-q1" href="#">Category 3</a></li>
</ul>
</div>
Your script would be along the lines of
var curDDText;
$("#btnPopup").on("click", function(){
curDDText = $(this).closest('dd').prev('dt').text();
});
$("#popupMenu-q1 ul li a").on("click", function(e){
selectCategory(this);
});
function selectCategory(elem){
alert($(elem).prop("name") + " - " + curDDText);
$("#popupMenu-q1").popup( "close" );
}
working DEMO
If you prefer the data-attribute route:
$("#btnPopup").on("click", function(){
var curDDText = $(this).closest('dd').prev('dt').text();
$("#popupMenu-q1 ul").jqmData("dttext", curDDText);
});
function selectCategory(elem){
var curDDText = $(elem).closest("ul").jqmData("dttext");
alert($(elem).prop("name") + " - " + curDDText);
$("#popupMenu-q1").popup( "close" );
}
data-attribute DEMO

Meteor only trigger template after selecting item from list

I have a typical scenario where there is a list view and then there's a details view. You get to the details view by selecting a list item. There's data in the record that of course will inform the layout view of the details. What I see is that the subtemplate's helper function is being called too soon (during the list view rendering) to have the data for the list details . Furthermore, it's not being called when I click an item in the list. What am I doing wrong? I'm using Meteor 0.8.2 with jQM 1.4.3.
The HTML looks as follows:
<!-- details page -->
<div data-role="page" data-theme="q" id="listdetail">
<div data-role="header" data-position="fixed">
<a data-rel="back" href="#" data-transition="slideleft" class="baack fa fa-arrow-left"></a>
<div id="detailTitle" class="headertitle"></div>
</div>
<!-- /header -->
<div data-role="content" class="ma-req-detail" id="details">
{{> qDetails}}
</div>
</div>
<!-- /details page -->
<template name="qList">
{{#each items}}
{{>qListItems}}
{{/each}}
</template>
<template name="qListItems">
<li>
<div id="msg-container-{{requestId}}" class="processing-msg">
<i class="fa fa-2x fa-times-circle"></i>
<p class="msg-text-{{requestId}}">Action pending...</p>
</div>
<a id="requestId" href="#listdetail" data-name="{{additionalProperties}}" data-transition="slide" class="{{#if isProcessing}}ui-disabled{{/if}}">
<p class="requestor">{{additionalProperties.requestedForUid}}</p>
<p class="description">week of {{additionalProperties.workWeekOf}}</p>
<p class="reqdate">total hours: </p>
</a>
</li>
</template>
<template name="qDetails" >
<div role="main" class="q-details">
<div data-role="navbar" class="week-nav">
<ul>
{{#each days}}
{{>navElements}}
{{/each}}
</ul>
</div>
</div>
<div class="ma-buttons ui-fieldcontain ui-footer-fixed">
<div data-role="controlgroup" data-type="horizontal" class="" data-position-fixed="true" data-position="bottom">
<a data-mini="true" href="#" id="approve-request"
class="ui-btn ui-btn-c ui-corner-r ui-icon-check ui-btn-icon-left ma-btn approve">Approve</a>
</div>
</div>
</template>
<template name="navElements">
<li><a id="{{day}}Nav" href="#{{day}}">{{day}}<br><span class="digital-date">{{date}}</span></a></li>
</template>
The JS bits are:
Template.qDetails.rendered = function() {
$('#details').trigger('create');
};
Template.qDetails.helpers({
days: function() {
//TODO need a way to delay this function to call when details template is shown
var dt = Session.get("record").additionalProperties.workWeekOf;
var days = [];
var weekday = new Array(7);
weekday[0] = "SAT";
weekday[1] = "SUN";
weekday[2] = "MON";
weekday[3] = "TUE";
weekday[4] = "WED";
weekday[5] = "THU";
weekday[6] = "FRI";
var dtVal = dt.getDate();
for (var i = 0; i < 7; i++) {
var dayObj = {};
dayObj.date = dtVal + i;
dayObj.day = weekday[i];
days.push(dayObj);
}
return days;
}
});
Template.qDetails.record = function () {
return Session.get("record");
};
In the code above the "days" helper function is being called when the list page is shown which results in an error because it is trying to pull the "workWeekOf" date from a record that hasn't been selected yet. How can I get to this only call once a record has been selected?
This is slightly confusing, since there's nothing in the above that shows how yourqDetails template gets rendered in the first place. However, assuming it does, you can just use:
var dt = Session.get("record") ? Session.get("record").additionalProperties.workWeekOf : [default date]
[default date] could be anything sensible (like new Date()), but you need to return something to avoid the error being thrown. This is a pretty common but very easily solved problem in Meteor - you just need a suitable default for when your Session variable or Collection isn't yet ready.

Nested ListView In Jquery Mobile with mvc

I create nested list view in Asp.net mvc with jQuery mobile, it has 2 sub view, when i navigate to first subview1 i can return back to main view, but when i navigate from subview1 to subview2 i can not back to subview1, since subview1 is somehow null.
in my layout page i put this script
<script>
$(document).on('mobileinit', function () {
$.mobile.page.prototype.options.addBackBtn = true;
$.mobile.page.prototype.options.backBtnText = "Back";
$.mobile.page.prototype.options.backBtnTheme = "a";
$.mobile.defaultPageTransition = "slide";
});
</script>
the main page is :
<script>
$(document).on('click', '[data-rel=back]', function (e) {
e.preventDefault();
var activepage = $.mobile.activePage.attr("id");
if (activepage == "schedule")
$.mobile.changePage($('#flight'), { transition: "slide", reverse: false });
if (activepage == "dayFlight") {
$.mobile.changePage($('#schedule'), { transition: "slide", reverse: false });
}
});
<div data-role="page" id="flight" data-add-back-btn="true">
<div data-role="content">
<ul id="flightListView" data-role="listview" data-inset="false" data-filter="true">
#foreach (var item in Model)
{
<li>
<a href="#Url.Action("Schedules", new { from = item.DepartureFrom, to = item.Destination })" data-direction="reverse" data-transition="slide">
<span class="ui-li-count ui-btn-up-c ui-btn-corner-all">#item.NumberOfFlights</span>
</a>
</li>
}
</ul>
</div>
the subview1 is:
<div data-role="page" data-add-back-btn="true" id="schedule">
<div data-role="content">
<ul id="scheduleListView" data-role="listview" data-inset="false" data-filter="false">
#foreach (var item in Model)
{
<li>
<a href="#Url.Action("DayFlights", new { from = from, to = to, date = item.Date })" data-direction="reverse" data-transition="slide">
<span class="lg">#Html.DisplayFor(modelItem => item.Day)</span>
<span class="lg number laligned">#Html.DisplayFor(modelItem => item.Date)</span>
<span class="ui-li-count ui-btn-up-c ui-btn-corner-all">#item.Nof</span>
</a>
</li>
}
</ul>
</div>
the subview2 is :
<div data-role="page" data-add-back-btn="true" id="dayFlight">
<div data-role="content">
<ul id="dayListView" data-role="listview" data-inset="true" data-filter="false">
#foreach (var item in Model)
{
<li>
<a href="#item.AgencyUrl" rel="external" data-ajax="false">
<span class="ui-li-count ui-btn-up-c ui-btn-corner-all">#item.Cap</span>
</a>
</li>
}
</ul>
</div>
something that i figure out, it is when i navigate to subview1, the mainview and the subview1 both of them are in DOM but then when i navigate to subview2, subview1 will replaced by subview2, so it means when i am at subview2 the subview1 does not exist in DOM.
in all cases $.mobile.activePage.prev('.ui-page'); return null, that is the reason why i decided to use if clause to determine to which page i should navigate back to, however when i want to navigate back from subview2 to subview1 it does not work.
how can i implement this senario?
thanks in advance

Can't click on dropdown on bootstrap navbar after something else on navbar has been clicked

I have a normal bootstrap navbar with some drop downs on it. When I click on a link in a drop down a modal box appears on screen, when I exit the modal box and then try to click on the drop down again on the navbar it won't work, an orange square border appears around the dropdown as if it can't get focus again or something. Any ideas why this could be happening?
<div class="navbar navbar-inverse navbar-fixed-top ">
<div class="navbar-inner" id="background">
<a class="brand" href="#Url.Action("RssIndex", "Home")">
<img src="~/Images/iconnewzy.png" alt="Newzy" ></a>
<ul class="nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="icon-user"></i>
<label style="display: inline; cursor: pointer;" id="friendsId">Friends</label><b class="caret"></b></a>
<ul class="dropdown-menu">
Add Friend
View Friends
</ul>
</li>
<b style="vertical-align: bottom !important; color: white">Hello, #User.Identity.Name!</b>
#Html.ActionLink("Log off", "LogOff", "Account", routeValues: null, htmlAttributes: new { #class = "btn btn-mini btn-primary" })
</ul>
</div>
</div>
I had the same problem. I've found a workaround in this article. Basically, you have to add this code to your page:
$(function() {
// Setup drop down menu
$('.dropdown-toggle').dropdown();
// Fix input element click problem
$('.dropdown input, .dropdown label').click(function(e) {
e.stopPropagation();
});
});

content of dynamically-added jQuery-ui tabs only showing once

I'm trying to create a tab set using jQuery UI that has some permanent tabs as well as some special purpose tabs. The special tabs are added temporarily: when the form they contain is submitted, the tabs are removed.
I've got this working except for one thing: after a tab is removed, if it is re-added later its content isn't shown, and I can't figure out why. I've distilled it down to this jsFiddle example, code also reposted below.
HTML:
<div id="tabs">
<ul>
<li>Foo</li>
</ul>
<div id="foo">
<h2>Foo Tab</h2>
</div>
<div id="bar" class="transient" style="display: none">
<h2><button type="button" class="close" style="float: right"><span class="ui-icon ui-icon-closethick">close</span></button>Bar Tab</h2>
</div>
<div id="baz" class="transient" style="display: none">
<h2><button type="button" class="close" style="float: right"><span class="ui-icon ui-icon-closethick">close</span></button>Baz Tab</h2>
</div>
</div>
<hr>
<button onClick="openTransientTab('bar', 'Bar')">Add Bar Tab</button>
<button onClick="openTransientTab('baz', 'Baz')">Add Baz Tab</button>
JavaScript:
$('#tabs').find('div.transient').find(".close").live('click', function() {
var footer_tabs = $('#tabs');
var tab_id = $(this).closest("div.transient").attr("id");
var index = footer_tabs.tabs("option", "selected");
footer_tabs.tabs("select", -1);
footer_tabs.tabs("remove", index);
});
function openTransientTab(id, title) {
var footer_tabs = $("#tabs");
footer_tabs.tabs("select", -1);
footer_tabs.tabs("select", "#" + id);
var selected = footer_tabs.tabs("option", "selected");
if (selected < 0) {
footer_tabs.tabs("add", "#" + id, title);
footer_tabs.tabs("select", "#" + id);
}
$("#" + id).css("display", "block");
}
$(function() {
var footer_tabs = $("#tabs");
footer_tabs.tabs({
collapsible: true,
selected: -1
});
});
When you load the page, the bar and baz tabs are created, but in their style, display is set to none which is why they are not visible originally. Inside the tab, when you hit the X, it actually removes the div for bar and baz completely. When you re-click to add the bar or baz tab after it closes, it recreates the div, but you are not putting anything within it. Add something like the following to once you create the tab.
document.getElementById("bar").innerHtml = whatever you want within it here
Before:
<div id="foo" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide">
<h2>Foo Tab</h2>
</div>
<div id="baz" class="transient" style="display: none">
<h2>
<button class="close" style="float: right" type="button">
<span class="ui-icon ui-icon-closethick">close</span>
</button>
Baz Tab
</h2>
</div>
<div id="bar" class="transient ui-tabs-panel ui-widget-content ui-corner-bottom" style="display: block;">
<h2>
<button class="close" style="float: right" type="button">
<span class="ui-icon ui-icon-closethick">close</span>
</button>
Bar Tab
</h2>
</div>
After opening and closing both
<div id="foo" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide">
<h2>Foo Tab</h2>
</div>
<div id="bar" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" style="display: block;"></div>
<div id="baz" class="ui-tabs-panel ui-widget-content ui-corner-bottom" style="display: block;"></div>
After Collecter provided the key insight about what wasn't working, I found a nicer way to preserve the tab content for reuse. I changed my close function to the following:
$('#tabs').find('div.transient').find(".close").live('click', function() {
var footer_tabs = $('#tabs');
var tab = $(this).closest("div.transient");
var index = footer_tabs.tabs("option", "selected");
footer_tabs.tabs("select", -1);
footer_tabs.tabs("remove", index);
footer_tabs.append(tab);
});

Resources