Why cannot create icons dynamically in ajax? - ajax

Normally, when I write the followings:
<a id="sta_numberOfIcons" class="icon-user" rel="popover"></a>
And js:
$("a[rel=popover]").each(function(){
$(this).popover({
trigger: 'hover',
placement: 'top',
html: true,
title:"Passenger Info",
content: "content "+$(this).attr('id')
})
.click(function(e) {
e.preventDefault()
});
});
It works and I can see a popover for the icon.But when I write the following code,to create the icons dynamically, but I cannot show popovers for the newly created icons.
html part:
Stations:
<select name="selectStation" id="selectStation" onchange="sta_callStation(this);"></select>
<a id="sta_numberOfIcons" class="icon-user" rel="popover"></a>
<div id="infoOfPassengers"></div>
<div id="distType"></div>
<div id="distParams"></div>
In Stations combobox, options are filled when the page is loaded.They are filled normally.
js function for getting the number of passengers from php, and create icons accordingly:
function sta_callStation(sel){
$('#noOfPassengers, #infoOfPassengers, #distType,#distParams').empty();
$('#sta_numberOfIcons').empty();
$.getJSON('Stations.php', function(station){
$.each(station, function(sta_key, sta_value) {
if(sel.value==sta_key)
{
$.each(sta_value.passengers, function(j,passengers)
{
var pas_icon = document.createElement("a");
pas_icon.className ='icon-user';
pas_icon.id='id_'+j;
pas_icon.setAttribute('href', '#');
pas_icon.setAttribute('rel', 'popover');
//alert('id_'+(j));
var empty=document.createElement("a");
empty.appendChild(document.createTextNode(" "));
document.getElementById('sta_numberOfIcons').appendChild(pas_icon);
document.getElementById('sta_numberOfIcons').appendChild(empty);
});
}
});
});
}
The icons appear in the page under the combobox.I just put to try, I don't know how to insert the new created icons to a tag.I just appended the newly created icons to tag.What is wrong here?Why I cannot show popovers for the created icons?Please help.

The JS code that you have which successfully wires-up the popover for elements $("a[rel=popover]") needs to execute after you have dynamically added your icons.
You could paste those lines into the end of the logic in sta_callStation() but it is probably better to put them into their own function and call that from sta_callStation().
Something like:
function bindMyPopovers() {
$("a[rel=popover]").each(function(){
$(this).popover({
trigger: 'hover',
placement: 'top',
html: true,
title:"Passenger Info",
content: "content "+$(this).attr('id')
})
.click(function(e) {
e.preventDefault()
});
});
}

Related

How to force CKEditor to process widgets when setting the HTML of an element

I have create a simple CKEditor widget that highlights the elements that have the class "pink".
I have also added a "Pinkify" button to the toolbar, which replaces the HTML of the selected element with some other elements that have the class "pink".
What I observe when I click the button is that widgets are not created for the freshly inserted elements. However, when I toggle between Source mode and WYSISYG mode, the widgets get created.
See the jsfiddle and its code:
CKEDITOR.replace('ck', {
allowedContent: true,
extraPlugins: 'pink'
});
CKEDITOR.plugins.add('pink', {
requires: 'widget',
init: function(editor) {
editor.widgets.add('pinkwidget', {
upcast: function(element) {
return element.hasClass('pink');
}
});
editor.addCommand('pinkify', {
editorFocus: 1,
exec: function(editor) {
var selection = editor.getSelection(),
selectedElement = selection.getStartElement();
if (selectedElement) {
selectedElement.setHtml("Let's have some <span class=\"pink\">pink</span> widget here!");
editor.widgets.checkWidgets(); // needed?
}
}
});
editor.ui.addButton('pinkify', {
label: 'Pinkify',
command: 'pinkify'
});
},
onLoad: function() {
CKEDITOR.addCss('.cke_widget_pinkwidget { background: pink; }');
}
});
I am aware of this question on Stackoverflow, but I can't get it to work with setHtml called on an element. Can you suggest how to modify the code so that widgets get created as soon as the HTML is updated?
According to the CKEditor team, it is normal that CKEDITOR.dom.element.setHtml does not instanciate widgets (see Widgets not initialised after calling setHtml on an element).
So the workaround they gave me was to rewrite the code that insert HTML in place of the selected element to:
if (selectedElement) {
selectedElement.setHtml("");
editor.insertHtml("Let's have some <span class=\"pink\">pink</span> widget here!");
}
For those like me who didn't know, editor.insertHTML inserts HTML code into the currently selected position in the editor in WYSIWYG mode.
Updated jsFiddle here.

CKEditor not editable in IE11 after ajax call

Example:
Jsfiddle
If the page is loaded the first time, the CKEditor is working right and the value of the editor can be edited. After hitting the button "ajax" which is calling the following function (cursor must be in the editor field):
function ajax_call() {
var html = "<textarea id=\"textarea\"><p>test 1</p><p>test 2</p><p>test 3</p></textarea><script type='text/javascript'>jQuery(document).ready(function() { ckEditor('textarea'); });<\/script>";
$.post("/echo/html/", { html: html }, function(data){
jQuery('#target').html(data);
});
}
it isn't possible to click on the text in IE11 to edit the value. Clicking beyond the text or left of it enabels the editor again.
Looks like creation of new textarea after CKEDITOR is initiated brakes editor in IE. Though i just tried to set data directly on instance of CKEDITOR and it worked fine,rather than creating new textarea tag.
function ajax_call() {
var html = "<p>test 4</p><p>test 5</p><p>test 6</p>";
$.post("/echo/html/", { html: html }, function(data){
//jQuery('#target').html(data); <-- Removed from original
CKEDITOR.instances['textarea'].setData(data)// <-- Added
});
}
function ckEditor(id) {
CKEDITOR.replace(id, {
language : 'de',
});
}
jQuery(document).ready(function() {
ckEditor('textarea');
});
Here is working example:
http://jsfiddle.net/2wq86gqs/15/

Kendo splitter control load right panel contents asynchronously

I have a Kendo splitter control with left/right panes. Inside the left pane I have a Kendo panel bar control that builds a navigation menu. Unfortunately I inherited this from another developer that left the company and I'm not familiar with the Kendo control.
It all works, but when the user clicks on a menu item, the entire page refreshes, That's for the birds! I want only the right panel to refresh.
Here's the code for the for the layout page:
<body>
#(Html.Kendo().Splitter().Name("splitter").Panes(panes => {
panes.Add().Size("220px").Collapsible(true).Content(#<text>
#Html.Partial("_Panelbar")
</text>);
panes.Add().Content(#<text>
<section id="main">
#RenderBody()
</section>
</text>);
}))
<script type="text/javascript">
$(document).ready(function () {
$('input[type=text]').addClass('k-textbox');
});
</script>
#RenderSection("scripts", required: false)
</body>
and here's the code for the panel partial view:
#(Html.Kendo().PanelBar().Name("panelbar")
.SelectedIndex(0)
.Items(items => {
items.Add().Text("Corporate").Items(corp =>
{
corp.Add().Text("Vendors").Action("Index", "Vendor");
corp.Add().Text("Materials").Action("Index", "CostMaterials");
corp.Add().Text("Packaging").Action("Index", "CostPackaging");
corp.Add().Text("Reports").Action("UnderConstruction", "Home", new { pageTitle = "Reports" });
});
}))
I tried replacing the .Action method on the PanelBar with LoadContentsFrom method. That replaced the content in the left pane. So I guess my question is, how do I target the right side of the splitter control?
Any help would be appreciated.
Thanks
-Alex
Your code maybe like this:
#(Html.Kendo().PanelBar().Name("panelbar")
.SelectedIndex(0)
.Items(items => {
items.Add().Text("Corporate").Items(corp =>
{
corp.Add().Text("Vendors").Url("javascript:void(0);")
.HtmlAttributes(
new {
#class= "helloWorld",
#data-href="/Vendor/Index"
});
});
}))
<script>
$document.ready(function(){
$('.helloWorld').click(function(){
var href = $(this).attr('data-href');
$('#main').load(href);
});
});
</script
UPDATE
There is one thing very important: I think the view /Vendor/Index have the same template with your current page.
It means that when you load /Vendor/Index into the right side. The right side will include entire content (include left panel again).
Solution
You have to create a new view(a template) , which just include your left menu,banner,...
Then, You have to remove all template of other views (which will be loaded into right side - /Vendor/Index , /CostMaterials/Index,...)
2.This way is not a good approach. But I think It will work.
//Reference : Use Jquery Selectors on $.AJAX loaded HTML?
<script>
$document.ready(function(){
$('.helloWorld').click(function(){
var href = $(this).attr('data-href');
$.ajax({
type: 'GET',
url: href,
success: function (data){
var rHtml = $('<html />').html(data);
$('#main').html(rHtml.find('#main'));
}
});
});
});
</script

making sub-menu stay open and selected when loading new page

I have a main menu and one of its options has an accordion effect on toggle with the following script:
$(document).ready(function(){
$(function(){
$("#accordion").accordion({
active: false,
autoHeight: false,
collapsible: true
});
});
});
When one of its sub-options is selected I add an active class with this:
jQuery.fn.slideFadeToggle = function(speed, easing, callback){
return this.animate({opacity: 'toggle', width: 'toggle'}, speed, easing, callback);
};
$(document).ready(function(){
$("#subNavUs").hide();
$("#us").click(function () {
$("#subNavSys").hide();
$("#subNavApp").hide();
$("#subNavAcc").hide();
$("#subNavUs").slideFadeToggle(800);
$('*').removeClass('active');
$(this).addClass('active');
return true;
});
$("#subNavSys").hide();
$("#sys").click(function () {
$("#subNavUs").hide();
$("#subNavApp").hide();
$("#subNavAcc").hide();
$("#subNavSys").slideFadeToggle(800);
$('*').removeClass('active');
$(this).addClass('active');
return true;
});
And this triggers a sub-menu, but when I select any of this new sub-menu's options to load a new page both the accordion menu and the sub-menu are back hidden. How can I make them stay open and show the active class I want to assign them?
Just added "navigation: true" to the accordion function. It was a beginner's mistake but I finally got it to work :)
I post it in case someone might have the same issue.

How to display a dialog when user clicks on a <img>?

Here's what I've made so far:
// somewhere in the page code...
<img alt="" src="images/frame.png" onclick="uploadImage()" />
I have created a jQuery script:
// in the head section of the page...
<script type="text/javascript">
$('#uploadContactImage').dialog({
title: 'Change contact image',
buttons: {
"Upload new image": function() {
$(this).dialog("close");
},
"Remove current image": function() {
$(this).dialog("close");
},
"Cancel": function() {
$(this).dialog("close");
}
}
});
</script>
Finally, I have a javascript file with the empty function:
function uploadImage() {
}
The use case should be: User clicks the image, the dialog pops up. Based on the button the user has clicked, certain functions should be called.
Please note that my image tag is generated through AJAX, i.e. the jQuery script is not connected to it. That's the first problem.
The second problem is that I don't know how to call the jQuery script to actually display the dialog.
The third and the last problem is that I don't know how to handle the choice the user makes.
As you must have concluded by now, I am a complete newbie when it comes to jQuery. Can you help me out to get started? Thanks.
Boris,
This is quite simple to do. Firstly, I would not use an onClick event as jQuery has much better ways to manage this. Instead, it should look as follows:
HTML:
<img alt="" src="images/frame.png" id="imageUpload" />
jQuery:
$('img#imageUpload').dialog({
title: 'Change contact image',
buttons: {
"Upload new image": function() {
$(this).dialog("close");
},
"Remove current image": function() {
$(this).dialog("close");
},
"Cancel": function() {
$(this).dialog("close");
}
}
});
First you'll need some hook, or path, to select the image element. Second, since it's added to the page after the document load you'll need to attach the event listener after the response.
select the element
So if you have control of the html returned via ajax add an id to it and select it trivially with jquery:
<img alt="" src="images/frame.png" onclick="uploadImage()" id="pickME" />
...and someplace in the ajax callback...
$("#pickME").click(...
If you can't add the id you'll have to drill down to it by starting from the wrapping element and looking for the img descendant.
attach the event
you can't attach the click event when the document is "ready" because the ajax hasn't inserted it into the document yet. So the thing here is to add the event handler after the img is inserted into the document. So you need to catch that event so you know when its time to add your click event.
ajax(...
success: function(data){
...stuff data into document...
$("#pickME").click(function(){
...attach the dialog to the element...
you might be out of your depth ;-)

Resources