Django has no response to anchor tag - django

test
...
<div class="tab-pane " id="test">
<table>
...
</table>
</div>
When #test anchor is clicked, the behavior should be logged in the server. So in urls.py, I defined something like this
url(r'#test$', views.log())
or
url(r'.*#test$', views.log())
But it seems it doesn't work.
I have to use anchor here, because I don't want to refresh the page.
Any ideas?

Here is some JavaScript that takes links with a href attribute starting with # and makes a request to https://localhost:8000/<whatever was after the hash sign> whenever the links are clicked. It's not robust and it needs to be modified for your circumstances, but maybe it works as a starting point.
var hashLinks = document.querySelectorAll('a[href^="#"]');
var i;
function hashLinkClicked(event) {
var hash, url, request;
// You probably want to allow default link behaviour here
event.preventDefault();
hash = this.hash;
// Cut hash character out of URL
url = 'http:/localhost:8000/' + hash.slice(1);
request = new XMLHttpRequest();
request.onreadystatechange = function () { /* Handle response here */ };
request.open('GET', url);
request.send();
}
for (i = 0; i < hashLinks.length; i++) {
hashLinks[i].addEventListener('click', hashLinkClicked);
}

Related

Dropdown dynamic in django ajax

I am using django for dynamic dropdown. There are two dropdown when the first dropdown was click and there is a subcategory for it, the second dropdown will show options. I want to disable the second dropdown if there is no subcategory for it. How can I do that?
$("#id_general-collision_type").change(function () {
const url = $("#form_incidentgeneral").attr("data-acc-url"); // get the url of the `load_cities` view
const collisionId = $(this).val(); // get the selected country ID from the HTML input
$.ajax({ // initialize an AJAX request
url: url, // set the url of the request (= /persons/ajax/load-cities/ )
data: {
'collision_type_id': collisionId // add the country id to the GET parameters
},
success: function (data) {
//console.log(data) // `data` is the return of the `load_cities` view function
$("#id_general-collision_subcategory").html(data); // replace the contents of the city input with the data that came from the server
let html_data = '<option value="">---------</option>';
data.forEach(function (collision_subcategory) {
html_data += `<option value="${collision_subcategory.id}">${collision_subcategory.sub_category}</option>`
});
console.log(html_data);
$("#id_general-collision_subcategory").html(html_data);
}
});
});
success: function (data) {
let select_element = $('select'); #Sub_category select
$(select_element).html(''); #Make Empty Select
for(let i=;i<data.length;i++){
let x = data[i];
let option_element = `<option value='${x['id']}'`>${x['sub_category']}</option>`;
$(select_element).append(option_element);
}
}

Changing image based on location data output

I am trying to show/echo users location on a webpage using maxmind geoip2 paid plan, I also want to show different images based on the state/city names output.
For example, if my webpage shows the user is from New York, I would like to show a simple picture of New York, if the script detects the user is from Washington, the image should load for Washington.
This is the snippet I have tried but doesn't work.
<script type="text/javascript">
if
$('span#region=("New York")') {
// Display your image for New York
document.write("<img src='./images/NY.jpg'>");
}
else {
document.write("<img src='./images/different.jpg'>");
}
</script>
This is the code in the header.
<script src="https://js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js" type="text/javascript"></script>
<script>
var onSuccess = function(geoipResponse) {
var cityElement = document.getElementById('city');
if (cityElement) {
cityElement.textContent = geoipResponse.city.names.en || 'Unknown city';
}
var countryElement = document.getElementById('country');
if (countryElement) {
countryElement.textContent = geoipResponse.country.names.en || 'Unknown country';
}
var regionElement = document.getElementById('region');
if (regionElement) {
regionElement.textContent = geoipResponse.most_specific_subdivision.names.en || 'Unknown region';
}
};
var onError = function(error) {
window.console.log("something went wrong: " + error.error)
};
var onLoad = function() {
geoip2.city(onSuccess, onError);
};
// Run the lookup when the document is loaded and parsed. You could
// also use something like $(document).ready(onLoad) if you use jQuery.
document.addEventListener('DOMContentLoaded', onLoad);
</script>
And this simple span shows the state name in body text of the Html when the page loads.
<span id="region"></span>
now the only issue is the image doesn't change based on users location, what am i doing wrong here?
Your example is missing some code, but it looks like you are running some code immediately and some code in a callback, a better way to do it is to have all the code in the callback:
// whitelist of valid image names
var validImages = ["NJ", "NY"];
// get the main image you want to replace
var mainImage = document.getElementById('mainImage');
if (mainImage) {
// ensure there is a subdivision detected, or load the default
if(geoipResponse.subdivisions[0].iso_code && validImages.includes( && geoipResponse.subdivisions[0].iso_code)){
mainImage.src = "./images/" + geoipResponse.subdivisions[0].iso_code + ".jpg";
} else {
mainImage.src = "./images/different.jpg";
}
}
Then just have the image you want to replace be:
<img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" id="mainImage" />
Notes:
If you are using a responsive image, make sure your transparent gif is the same ratio height of to width as your final image to avoid page reflows.
You will have to load the different.jpg in the onError callback as well.

Sitecore 8 EXM add a contact to list from listmanager

I'm using Sitecore 8 and the new Email Experience Manager module.
I have configured a newsletter email message with an empty list from the listmanager as recipients.
When subscribing for the newsletter via a selfmade form, I receive an email address and a name.
Now I want to make a new contact with this mail and name and add it to the list in my listmanager via code.
Is there any way to call this list via the api and add a contact to it?
To create a contact, you can use the sample code below, the contact name is usually the domain name plus the username, e.g. domain\username.
public static Contact CreateContact([NotNull] string contactName, [NotNull] string contactEmail, [NotNull] string contactLanguage)
{
Assert.ArgumentNotNullOrEmpty(contactName, "contactName");
Assert.ArgumentNotNullOrEmpty(contactEmail, "contactEmail");
Assert.ArgumentNotNullOrEmpty(contactLanguage, "contactLanguage");
var contactRepository = new ContactRepository();
var contact = contactRepository.LoadContactReadOnly(contactName);
if (contact != null)
{
return contact;
}
contact = contactRepository.CreateContact(ID.NewID);
contact.Identifiers.AuthenticationLevel = AuthenticationLevel.None;
contact.System.Classification = 0;
contact.ContactSaveMode = ContactSaveMode.AlwaysSave;
contact.Identifiers.Identifier = contactName;
contact.System.OverrideClassification = 0;
contact.System.Value = 0;
contact.System.VisitCount = 0;
var contactPreferences = contact.GetFacet<IContactPreferences>("Preferences");
contactPreferences.Language = contactLanguage;
var contactEmailAddresses = contact.GetFacet<IContactEmailAddresses>("Emails");
contactEmailAddresses.Entries.Create("test").SmtpAddress = contactEmail;
contactEmailAddresses.Preferred = "test";
var contactPersonalInfo = contact.GetFacet<IContactPersonalInfo>("Personal");
contactPersonalInfo.FirstName = contactName;
contactPersonalInfo.Surname = "recipient";
contactRepository.SaveContact(contact, new ContactSaveOptions(true, null));
return contact;
}
After creating the contact, use the following sample code to add the contact to a recipient list.
var repository = new ListManagerCollectionRepository();
var recipientList = repository.GetEditableRecipientCollection(recipientListId);
if (recipientList != null)
{
var xdbContact = new XdbContactId(contactId);
if (!recipientList.Contains(xdbContact, true).Value)
{
recipientList.AddRecipient(xdbContact);
}
}
Essentially you can follow this example
<%# Page Language="c#" %>
<%# Import Namespace="Sitecore.Analytics" %>
<%# Import Namespace="Testing.ContactFacets.Model" %>
<!DOCTYPE html>
<html>
<head>
<title>Add Employee Data</title>
</head>
<body>
<%
var contact = Tracker.Current.Contact;
var data = contact.GetFacet<IEmployeeData>("Employee Data");
data.EmployeeId = "ABC123";
%>
<p>Employee data contact facet updated.</p>
<p>Contact ID: <b><%=contact.ContactId.ToString()%></b></p>
<p>Employee #: <b><%=data.EmployeeId%></b></p>
</body>
</html>
The changes are then written when the session is abandoned, like so
<%# Page language="c#" %>
<script runat="server">
void Page_Load(object sender, System.EventArgs e) {
Session.Abandon();
}
</script>
<!DOCTYPE html>
<html>
<head>
<title>Session Abandon</title>
</head>
<body>
</body>
</html>
Follow this link for the source and more information - http://www.sitecore.net/learn/blogs/technical-blogs/getting-to-know-sitecore/posts/2014/09/introducing-contact-facets
I have had the exact same issue, i.e. the list manager reports 0 contacts after adding the contact to the recipient list.
I have investigated the issue closer and found that adding a contact to a recipient list actually just sets a field on the contact in the "sitecore_analytics_index" index (assuming you use Mongo/XDB as the underlying storage). Specifically, Sitecore should update the "contact.tags" field on the contact document with the value "ContactLists:{recipientListGuid}". I tried opening the index with Luke to verify that this field was indeed not being set in the index. The index is located in C:\inetpub\wwwroot[Sitename]\Data\indexes\sitecore_analytics_index.
This led me to the conclusion, that you have to save the contact after adding him to the recipient list.
Summing up, the following code works for me:
var ecm = EcmFactory.GetDefaultFactory();
XdbContactId contactId = /* some valid contact id */;
LeaseOwner leaseOwner = new LeaseOwner("UpdateContact-" + Guid.NewGuid().ToString(), LeaseOwnerType.OutOfRequestWorker);
Sitecore.Analytics.Tracking.Contact contact;
string webClusterName;
var status = ecm.Gateways.AnalyticsGateway.TryGetContactForUpdate(contactId.Value,
leaseOwner,
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(5),
out contact, out webClusterName);
var recipientList = ecm.Bl.RecipientCollectionRepository.GetEditableRecipientCollection(recipientListId);
if (recipientList != null)
{
if (!recipientList.Contains(contactId, true).Value)
{
recipientList.AddRecipient(contactId);
}
}
contact.ContactSaveMode = ContactSaveMode.AlwaysSave;
var contactRepository = new ContactRepository();
var success = contactRepository.SaveContact(contact, new ContactSaveOptions(true, leaseOwner));
Note, the above code is used in an update-scenario. In your case, I guess you just have to move this code:
contactRepository.SaveContact(contact, new ContactSaveOptions(true, null));
After this:
var recipientList = EcmFactory.GetDefaultFactory().Bl.RecipientCollectionRepository.GetEditableRecipientCollection(recipientListId);
if (recipientList != null)
{
var xdbContact = new XdbContactId(contactId);
if (!recipientList.Contains(xdbContact, true).Value)
{
recipientList.AddRecipient(xdbContact);
}
}
UPDATE: Actually the above only works if the contact saved is the contact currently tracked by Sitecore Analytics.
in case you have a tracker available and you dont need the update immediately, the following should work (note that the contact is added to the list upon session expiration):
//private const string ContactListTagName = "ContactLists";
var contact = Tracker.Current.Contact;
// Identify
if (contact.Identifiers.IdentificationLevel < ContactIdentificationLevel.Known)
{
Tracker.Current.Session.Identify(email);
}
// Set Email
var contactEmail = contact.GetFacet<IContactEmailAddresses>("Emails");
// Create an email address if not already present
// This can be named anything, but must be the same as "Preferred" if you want
// this email to show in the Experience Profiles backend.
if (!contactEmail.Entries.Contains("Preferred"))
contactEmail.Entries.Create("Preferred");
// set the email
var emailEntry = contactEmail.Entries["Preferred"];
emailEntry.SmtpAddress = email;
contactEmail.Preferred = "Preferred";
// set FirstName and Surname (required for List Manager, "N/A" might not be ideal but I don't know how Sitecore behaves with empty strings)
var personal = contact.GetFacet<IContactPersonalInfo>("Personal");
personal.FirstName = personal.FirstName ?? "N/A";
personal.Surname = personal.Surname ?? "N/A";
// Add preferred language
var preferences = contact.GetFacet<IContactPreferences>("Preferences");
preferences.Language = Context.Language.Name;
// Here is the actual adding to the list by adding tags
using (new SecurityDisabler())
{
var id = ID.Parse("CONTACTLISTID");
contact.Tags.Set(ContactListTagName, id.ToString().ToUpperInvariant());
}
Greetz,
Markus

angularjs not responding the GET method

i am relatively new in django and angualarJs.The problem is that angularJs is not responding the get method properly.I have a webpage developed by django where i have a search field.For the execution of search i use a angularJs functionality that is ng-submit and write angularJs code to return value using get method.May be i made a mistake here.you can see my code... here is my template which containing the angularJs also...
<div class="navbar navbar-default " ng-controller="NavCtrl">
<form action="" class="navbar-form navbar-right" ng-submit="search()">
<input class="form-control col-lg-8" type="text" placeholder="Search" ng-model="term"></input>
</form>
</div>
<script>
app.controller("NavCtrl", ['$scope', '$http', '$location', '$q', '$timeout',
function NavCtrl($scope, $http, $location, $q, $timeout) {
$scope.results = ["Test"];
$scope.term = "";
$scope.reqs = "5";
$scope.pics = "45";
$scope.ddata = "asdasd";
$scope.ddata = $http.post("{% url 'get-nav-info' %}").success(
function (result) {
//$scope.reqs = result.data.data.num_request;
//$scope.pics = result.data.data.num_photo;
return result.data;
}
);
//$scope.reqs = $scope.ddata.num_request;
//$scope.pics = $scope.ddata.num_photo;
$scope.search = function () {
//alert("test");
//$location.absUrl("{% url 'search-term-show' %}").search({'term':$scope.term}).apply();
//$location.path("{% url 'search-term-show' %}").search({'term':$scope.term}).apply();
$http.get("{% url 'search-term-show' %}?term=" + $scope.term).success(function (result) {
return result.data;
});
//$scope.$apply();
}
}
]);
</script>
now the problem is that while i press enter ,there is no result,but if i manually write this URL which is http://www.kothay.com/searchphoto/?term=a in the address bar then the result is showing .In mention,this url is the that url which should be appear in the address bar when i press the enter to search my photos.But with the enter press its not appearing in the address bar and that's why the results are not showing.I hope you can understand what i am trying to say.May be there is a mistake in my code.Please help me to fix this problem.
You are doing thing wrong.
1st, the success is a defer of get, so return result.data and returns it to the get deferred and there it goes to the heaven. So if you would like to keep the current architecture it should look more like this
$scope.search = [];
getsearch = function () {
$http.get("{% url 'search-term-show' %}?term=" + $scope.term).success(function (result) {
$scope.search = result.data;
});
};
getsearch();
2nd that can still not update your UI cuz if the ctrl function is over and the digest is over before your response it wont update your UI cuz its in another scope (not $scope, but the programmatically term scope). The solution to this is to put your data in a service and in your ctr just do.
function ctrl($scope, myservice){
$scope.data = myservice;
}
ng-repeat="x in data.results"
Here is a full tutorial http://bresleveloper.blogspot.co.il/2013/08/breslevelopers-angularjs-tutorial.html
And last thing its just a good practice to always have .error(...)

getting a user-inputed variable in django template wihtout using forms

I have a django template which also has a div element that takes in a user_inputed value.
When the value is entered, I call a javascript function say onSubmit(user_input)
<input type="text" class= "inputtext" onKeyPress="return onSubmit(this.value)">
Now in this onSubmit() function which now has the user-inputted value user_input, I want to be able to use url patterns to a direct to a view, like
function onSubmit(user_input) {window.location = "{% url myview user_input %}";}
The problem here is that since user_input is empty when the template is loaded, the url-view reverse lookup gives an error. Is there a way to trigger this lookup only when the onSubmit function is called.
I know form is an alternative, but it just feels like it'll be an overkill for this situation.
You can get the URL via AJAX:
views.py:
def get_url(request):
name = request.GET.get('name')
args = reguest.GET.get('args', [])
kwargs = request.GET.get('kwargs', {})
try:
url = django.core.urlresolvers.reverse(name, args=args, kwargs=kwargs)
except NoReverseMatch:
url = None
return django.http.HttpResponse(url)
urls.py
#...
('^url$', get_url)
#...
js:
function onSubmit(user_input) {
var args = [user_input];
jQuery.get('/url', {'args': args}, function(data) {
var url = data;
if (url) {
window.location = url;
} else {
alert('fail');
}
});
}
Alternatively, if your URL rule is simple enough, you can use some placeholder when resolving and URL, and before submitting the form you should replace it with real input:
var fakeUrl = '{% url myview "%s%" %}';
function onSubmit(user_input) {
window.location = fakeUrl.replace('%s%', user_input);
}