I have a page that it using jEditable, and I want to load dynamically the options of a picklist (Depending of the current element).
I have the following example in fiddle:
http://jsfiddle.net/mbv401920150/2rdco6qL/1/
$(document).ready(function() {
$('.edit').editable(function(value, settings) {
console.log(this);
console.log(value);
console.log(settings);
return(value);
}, {
data : " {'E':'E','F':'F','G':'G', 'selected':'F'}", // <---- I WANT TO CHANGE THIS CODE
// ******************************************
// DYNAMIC LOAD - DEPENDING OF THE ELEMENT ID
// ******************************************
// data : function(currentElement) {
// if(currentElement.id == "A") return " { '1':'1', '2':'2', '3':'3' }";
// else return " { 'A':'A', 'B':'B', 'C':'C' }";
// }
type : 'select',
onblur: 'submit'
});
});
I want retrieve the list of specific options depending of the element.
This could be possible?
I figured out how accomplish this task, I include an additional class per each element.
Here is a full solution:
http://jsfiddle.net/mbv401920150/2rdco6qL/3/
$(document).ready(function() {
$('.letter, .number').each(function(i, e) {
$(e).editable(function(value, settings) {
console.log(this);
console.log(value);
console.log(settings);
return (value);
}, {
data: ($(e).hasClass('letter') ?
" { 'A':'A', 'B':'B', 'C':'C' }" :
" { '1':'1', '2':'2', '3':'3' }"),
type: 'select',
onblur: 'submit'
});
});
});
If is a dynamic generation (on mouse over, on click); I remove the auxiliary class after the initialization of jEditable.
Related
I have a data, when I update the data (using modal), select option work correctly
When I close the modal, and I click the edit button again, something wrong with select option:
This is my edit modal ajax:
// Function for edit modal plan schedule
$('body').on('click', '.editPlanSchedule', function() {
var Item_id = $(this).data('id');
$.get("/quotation/getEditPlanSchedule" + '/' + Item_id, function(data) {
console.log(data['product_plan']);
$('.modal-title-edit').html("Edit Plan Schedule Item");
$('#saveBtn').val("Update");
$('#updatePlanSchedule').modal('show');
$('#id').val(data['data'].id);
$('#qno').val(data['data'].qno);
$('#b_amount').val(data['data'].b_amount);
// $('#product_plan_edit').val(data.product_plan);
data['product_plan'].forEach(function(item, index) {
$('#product_plan_edit').append($('<option>', {
id: item.id,
value: item.productplanID,
text: item.productplanID
}));
if(data['data'].product_plan == item.productplanID){
$('#'+item.id).attr('selected',true);
}
});
})
});
This is the method from controller:
public function getEditPlanSchedule($id)
{
$item['data'] = QuotationPlanSchedule::find($id);
$item['product_plan'] = ProductPlan::orderby('id', 'asc')->get();
return response()->json($item);
}
You have to clear all options before adding again:
$("#product_plan_edit").empty();
Either .empty the container or don't use append (better for the DOM update)
I am a little confused about your use of data['data'].product_plan to test the ID. In any case you can see the principle
$('#product_plan_edit').html(
data['product_plan'].map(item => `<option value="${item.productplanID}">${item.productplanID}</option>`).join('')
);
$('#product_plan_edit').val(data['data'].product_plan); // select item.productplanID === data['data'].product_plan
I have been trying to get the tag of a deleted chip from the div in the Materialize chips class, but nothing is working.
Here is what I have already tried.
$('.chips').on('chip.delete', function(e, chip){
console.log(chip);
console.log(e);
console.log(chip.tag);
});
None of the above is working.
With just only console.log(chip), I get undefined error in JavaScript console, but the function is firing when I delete the chip. I am just not able to get the value of tag of deleted chip. I want to store the tag in a variable.
I am creating chips dynamically on Materialize date select:
$('#pm_date').change(function () {
var chipvalue = $(this).val();
if (chipvalue !== "") {
// checking if tag already exits
if ($("#date_chip_select:contains(" + chipvalue + ")").length > 0) {
alert('Date already selected');
} else {
var appendstring = "<div class='chip' id='date_chip_child_" + chip_id + "'>" + chipvalue + "<i class='material-icons close'>close</i></div>";
}
}
});
Here is the fiddle: https://jsfiddle.net/hq22mne4/1/
chips.js, which is part of materialize, doesn't seem to expose any methods for adding or removing chips programmatically. It seems to exclusively listen for an enter keydown event and then internally add the chip.
So, I stitched together a workaround that does just that. I set potential chip's value within your onchange event:
$("#datechips").find('input').val($(this).val());
And create the chip when date picker is closed:
$('.datepicker').pickadate({
selectMonths: true,
selectYears: 15,
onClose: function() {
// add chip via filling the input and simulating enter
$("#datechips").find('input').trigger({ type : 'keydown', which : 13 });
},
});
It may not be ideal, but you should be able to tailor this going forward.
https://jsfiddle.net/j3ej8240/
I've also had a lot of trouble working this out. This is how I capture the add and delete chip events without using jQuery:
function chipDeleted(e, data) {
console.log("Chip was deleted with text: " + data.childNodes[0].textContent);
}
function chipAdded(e, data) {
console.log("Chip was added with text: " + data.childNodes[0].textContent);
}
//
document.addEventListener("DOMContentLoaded", function (e) {
console.log("DOM fully loaded and parsed");
var firstTag = "Initial Tag";
var elems = document.querySelectorAll('.chips');
var instances = M.Chips.init(elems, {
data:[{
tag: firstTag
}],
autocompleteOptions: {
limit: Infinity,
minLength: 1
},
placeholder: "No search...",
onChipDelete: function (e, data) { chipDeleted(e, data) },
onChipAdd: function (e, data) { chipAdded(e, data) }
});
});
And my HTML part is like this:
<body>
<div class="chips search-history"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script>
</body>
I'm having trouble adding classes to selected image in ckeditor. What I came up with is this http://pokit.org/get/img/8d89802e1d6f6371f5bc326898d8b414.jpg.
I added 2 buttons for selecting whether whether a picture is in portrait or landscape mode. You can select either of them or none, and add costum height/width.
Here is my code:
CKEDITOR.replace('maindesc', {
"extraPlugins": "imgbrowse",
"filebrowserImageBrowseUrl": "/ckeditor/plugins/imgbrowse",
on: {
instanceReady: function() {
this.dataProcessor.htmlFilter.addRules( {
elements: {
img: function( el ) {
// Add an attribute.
if ( !el.attributes.alt ) {
el.attributes.alt = 'Img';
el.addClass('ckeditorImg');
if (Landscape == 1) {
el.addClass('ckLandscape');
el.attributes['style'] = '';
}
else if (Portrait == 1) {
el.addClass('ckPortrait');
el.attributes['style'] = '';
}
}
}
}
} );
}
}
});
So as far as I understand this goes through all, so I wrote that if the image has no alt attribute to add one and add the classes I want. Unfortunately this approach doesn't allow me to change the class on selected image when a user wants to change it, but instead he has to delete the image, select it again and then choose class.
My question is whether there is a way to get to currently selected image instead of going through all <img> tags in ckeditor and change its class.
Here is an example for how to add a new button to ckeditor that is enabled/disables based on the element that you currently select and add a class to that specific element (in this example it's for images, however you can use it in any way you want).
// Set the callback function
var setLandscapeClass = {
exec: function(editor) {
editor.getSelection().getStartElement().addClass('ckLandscape')
}
}
//Create the plugin
CKEDITOR.plugins.add('setLandscapeClass', {
init: function(editor) {
editor.addCommand('setLandscapeClass', setLandscapeClass);
editor.ui.addButton("setLandscapeClass", {
label: 'Set Landscape Class',
icon: '',
command: 'setLandscapeClass'
});
}
});
// Create the instance and add the plugin
CKEDITOR.replace( 'editor1', {
extraPlugins: 'setLandscapeClass',
allowedContent: true
});
// enable/disable the button based on the selection of the text in the editor
CKEDITOR.instances.editor1.on( 'selectionChange', function( evt ) {
var landscapeButton = this.getCommand( 'setLandscapeClass' );
if ( evt.data.path.lastElement.is( 'img' ) ) {
landscapeButton.enable();
} else {
landscapeButton.disable();
}
});
You can see a working demo here:
https://jsfiddle.net/7nm9q1qv/
I only created 1 button, and there is no icon there. I think you can use that code to create also the second button (for portrait class).
Update - add item to the context menu
In order to add a new item to the context-menu you should add this code:
// Add the context-menu
if (editor.addMenuItem) {
editor.addMenuGroup('testgroup');
editor.addMenuItem('setLandscapeItem', {
label: 'Set landscape class',
command: 'setLandscapeClass',
group: 'testgroup'
});
}
// On contextmenu - set the item as "visible" by the menu
if (editor.contextMenu) {
editor.contextMenu.addListener(function(element, selection) {
if (element.hasClass('ckLandscape') === false) {
return { setLandscapeItem: CKEDITOR.TRISTATE_ON };
}
});
}
Inside the init function of the plugin you add.
You can see that I added this line:
if (element.hasClass('ckLandscape') === false) {
(Which you can remove) only to give you an example of how to show the item in the menu only if the ckLandscape class doesn't exists for this image.
The updated version of the jsfiddle is here:
https://jsfiddle.net/7nm9q1qv/1/
I am using the following code to convert unoredered html list into a select drop down list:
jQuery(document).ready( function($) {
//build dropdown - main navigation
$("<select />").appendTo(".region-menu-inner nav");
// Create default option "Go to..."
$("<option />", {
"selected": "selected",
"value" : "",
"text" : "Navigate..."
}).appendTo("nav select");
// Populate dropdowns with the first menu items
$(".region-menu-inner li a").each(function() {
var el = $(this);
$("<option />", {
"value" : el.attr("href"),
"text" : el.text()
}).appendTo(".region-menu-inner select");
});
//make responsive dropdown menu actually work
$(".region-menu-inner select").change(function() {
window.location = $(this).find("option:selected").val();
});
});
At the same time, I am using Simple dialog module for Drupal to create modular window. This module comes with only one js file. The code this module is using is below:
/*
#file
Defines the simple modal behavior
*/
(function ($) {
/*
Add the class 'simple-dialog' to open links in a dialog
You also need to specify 'rev="<selector>"' where the <selector>
is the unique id of the container to load from the linked page.
Any additional jquery ui dialog options can be passed through
the rel tag using the format:
rel="<option_name1>:<value1>;<option_name2>:<value2>;"
e.g. <a href="financing/purchasing-options" class="simple-dialog"
rel="width:900;resizable:false;position:[60,center]"
rev="content-area" title="Purchasing Options">Link</a>
NOTE: This method doesn't not bring javascript files over from
the target page. You will need to make sure your javascript is
either inline in the html that's being loaded, or in the head tag
of the page you are on.
ALSO: Make sure the jquery ui.dialog library has been added to the page
*/
Drupal.behaviors.simpleDialog = {
attach: function (context, settings) {
// Create a container div for the modal if one isn't there already
if ($("#simple-dialog-container").length == 0) {
// Add a container to the end of the body tag to hold the dialog
$('body').append('<div id="simple-dialog-container" style="display:none;"></div>');
try {
// Attempt to invoke the simple dialog
$( "#simple-dialog-container", context).dialog({
autoOpen: false,
modal: true,
close: function(event, ui) {
// Clear the dialog on close. Not necessary for your average use
// case, butis useful if you had a video that was playing in the
// dialog so that it clears when it closes
$('#simple-dialog-container').html('');
}
});
var defaultOptions = Drupal.simpleDialog.explodeOptions(settings.simpleDialog.defaults);
$('#simple-dialog-container').dialog('option', defaultOptions);
}
catch (err) {
// Catch any errors and report
Drupal.simpleDialog.log('[error] Simple Dialog: ' + err);
}
}
// Add support for custom classes if necessary
var classes = '';
if (settings.simpleDialog.classes) {
classes = ', .' + settings.simpleDialog.classes;
}
$('a.simple-dialog' + classes, context).each(function(event) {
if (!event.metaKey && !$(this).hasClass('simpleDialogProcessed')) {
// Add a class to show that this link has been processed already
$(this).addClass('simpleDialogProcessed');
$(this).click(function(event) {
// prevent the navigation
event.preventDefault();
// Set up some variables
var url = $(this).attr('href');
// Use default title if not provided
var title = $(this).attr('title') ? $(this).attr('title') : settings.simpleDialog.title;
if (!title) {
title = $(this).text();
}
// Use defaults if not provided
var selector = $(this).attr('name') ? $(this).attr('name') : settings.simpleDialog.selector;
var options = $(this).attr('rel') ? Drupal.simpleDialog.explodeOptions($(this).attr('rel')) : Drupal.simpleDialog.explodeOptions(settings.simpleDialog.defaults);
if (url && title && selector) {
// Set the custom options of the dialog
$('#simple-dialog-container').dialog('option', options);
// Set the title of the dialog
$('#simple-dialog-container').dialog('option', 'title', title);
// Add a little loader into the dialog while data is loaded
$('#simple-dialog-container').html('<div class="simple-dialog-ajax-loader"></div>');
// Change the height if it's set to auto
if (options.height && options.height == 'auto') {
$('#simple-dialog-container').dialog('option', 'height', 200);
}
// Use jQuery .get() to request the target page
$.get(url, function(data) {
// Re-apply the height if it's auto to accomodate the new content
if (options.height && options.height == 'auto') {
$('#simple-dialog-container').dialog('option', 'height', options.height);
}
// Some trickery to make sure any inline javascript gets run.
// Inline javascript gets removed/moved around when passed into
// $() so you have to create a fake div and add the raw data into
// it then find what you need and clone it. Fun.
$('#simple-dialog-container').html( $( '<div></div>' ).html( data ).find( '#' + selector ).clone() );
// Attach any behaviors to the loaded content
Drupal.attachBehaviors($('#simple-dialog-container'));
});
// Open the dialog
$('#simple-dialog-container').dialog('open');
// Return false for good measure
return false;
}
});
}
});
}
}
// Create a namespace for our simple dialog module
Drupal.simpleDialog = {};
// Convert the options to an object
Drupal.simpleDialog.explodeOptions = function (opts) {
var options = opts.split(';');
var explodedOptions = {};
for (var i in options) {
if (options[i]) {
// Parse and Clean the option
var option = Drupal.simpleDialog.cleanOption(options[i].split(':'));
explodedOptions[option[0]] = option[1];
}
}
return explodedOptions;
}
// Function to clean up the option.
Drupal.simpleDialog.cleanOption = function(option) {
// If it's a position option, we may need to parse an array
if (option[0] == 'position' && option[1].match(/\[.*,.*\]/)) {
option[1] = option[1].match(/\[(.*)\]/)[1].split(',');
// Check if positions need be converted to int
if (!isNaN(parseInt(option[1][0]))) {
option[1][0] = parseInt(option[1][0]);
}
if (!isNaN(parseInt(option[1][1]))) {
option[1][1] = parseInt(option[1][1]);
}
}
// Convert text boolean representation to boolean
if (option[1] === 'true') {
option[1]= true;
}
else if (option[1] === 'false') {
option[1] = false;
}
return option;
}
Drupal.simpleDialog.log = function(msg) {
if (window.console) {
window.console.log(msg);
}
}
})(jQuery);
Link that is using this module, in the source looks like this:
<a href='/user' name='user-login' id='user-login' class='simple-dialog' title='Login ' rel='width:400;resizable:false;position:[center,60]'>Log in</a>
The problem is that when you click on that link, it takes a second or two to load the popup and when it actually loads, second set of select dropdown list is being generated. If you click login link one more time, it generates third select list. Basically it duplicates whatever is converted from ul li into select list.
Thanks for help in advance.
jQuery(document).ready( function($) {
$(".region-menu-inner nav").empty(); //empty here
//build dropdown - main navigation
$("<select />").appendTo(".region-menu-inner nav");
// Create default option "Go to..."
$("<option />", {
"selected": "selected",
"value" : "",
"text" : "Navigate..."
}).appendTo("nav select");
// Populate dropdowns with the first menu items
$(".region-menu-inner li a").each(function() {
var el = $(this);
$("<option />", {
"value" : el.attr("href"),
"text" : el.text()
}).appendTo(".region-menu-inner select");
});
//make responsive dropdown menu actually work
$(".region-menu-inner select").change(function() {
window.location = $(this).find("option:selected").val();
});
});
I have the following code which is run at the end of a long table that has several button.enter-match elements:
$("button.enter-match")
.button()
.on('click', function() {
$("form.enter-match").dialog({
modal: true,
height: 'auto',
width: 200,
close: function() {
$("form.enter-match input[name='code']").val('');
},
open: function() {
$("form.enter-match input[name='code']").val('').focus();
},
buttons: {
Set: function() {
pid = $(this).parents("[data-pid]").data('pid');
if ($("form.enter-match input[name='code']").val() == '') {
alert('Code empty!');
return false;
}
$.post(
request_url,
{
'action': 'set_match',
'pid': pid,
'code': $("form.enter-match input[name='code']").val()
},
function (data) {
error_handler(data);
if (data['error'] == null) {
$("tr#pid-" + pid + " td.code:first div").html('<i>' + $("form.enter-match input[name='code']").val() + '</i>');
$("form.enter-match").dialog('close');
}
},
'json'
);
}
}
});
});
The line pid = $(this).parents("[data-pid]").data('pid'); does not get the pid data value because form#enter_match is created at the very top of the document to be reused in the code as needed. It therefore will not have a parent with the [data-pid] attribute, however, button.enter-match will. How do I get the value in [data-pid] for this particular button.enter-match from within the $("form.enter-match").dialog() portion of the code?
Could not figure out a way to get the next object up, so I simply moved pid = $(this).parents("[data-pid]").data('pid'); to the next scope up under the line .on('click', function() { which solved the problem in all instances.
Thanks to all who pointed out my bad coding practice with regards to IDs and classes. I've updated my coding style to reflect the better principals.