Changing data-attribute on select2 - jquery-select2

I working on an older legacy system using select2 3.5.2.
It's using the older hidden field method, and it currently passes data like so:
<input class="select2" data-url="/mapscrSearch/filterdata" data-parent="3" data-model="VMapscreenCategories" data-tags="1" data-searchterm="name" data-showitem="name" data-hiddenfield=".opcode_filters" data-allowuserinput="" data-enabled="1" type="text" value="" name="opcode_id" id="opcode_id" tabindex="-1" style="display: none;">
Right now, I have a small jquery function that changes the data-parent on the fly, and pulls in the correct data depending on the parent id; This works if I set data-parent manually, but when changing the data-parent via jquery it doesn't update the select2 component.
For example, I currently have:
$(document).ready(function(){
var opCodeFamily = $('#category_parent');
var opCodeParentId = $('#opcode_parent_id');
var opCodeDataUrl = $('#opcode_id');
// Set default
$(opCodeParentId).val($(opCodeFamily).val());
$(opCodeDataUrl).attr('data-parent', opCodeParentId.val());
// Change the value from parent select
$(opCodeFamily).change(function(){
$(opCodeParentId).val($(opCodeFamily).val());
$(opCodeDataUrl).attr('data-parent', opCodeParentId.val()).trigger("change");
console.log('data-parent set to: ' + opCodeParentId.val() + ', select2 passing: ' + opCodeDataUrl.data('parent'));
}).trigger("change")
});
I can see it changing the data-parent in the console and inspector, but select2 is still passing the original value. I've looked at trigger, but this doesn't seem to do anything. Is there something I'm missing?

Related

Removing selected option in multiple select2 clears all options

Using Laravel livewire, bootstrap 5 modal and select 2.
Select2 (s2) without multiple works fine. It's populated, selections save to the component, clearing is also fine.
When an s2 has multiple attribute, removing a selected option clears all the options and nothing is displayed in the results drop down. When adding a selection, this doesn't happen.
If I do a dispatchBrowserEvent and re-init the s2 it does work again.
My question is why does removing an s2 option require a re-init but an add doesn't.
Seems to be something to do with the rendering in render().
Some code...
Blade:
<div wire:ignore>
<select id="selectedTrades" wire:model.defer="selectedTrades" class="select-2" multiple="multiple" data-field="selectedTrades" data-allow-clear="false">
#foreach ($contractor_trades as $trade)
<option value="{{ $trade['id'] }}">{{ $trade['name'] }}</option>
#endforeach
</div>
Standard stuff. wire.ignore around the s2. The modal has wire:ignore.self.
JS:
$('.select-2').on('change', function (e)
{
var $this = $(this);
livewire.emit('setSelect2Property', $this.attr('data-field'), $this.val());
});
Component:
public function setSelect2Property($property, $value)
{
$this->$property = $value;
}
Just sets $this->selectedTrades to the array sent.
Adding:
The drop down has the options as expected.
Removing:
The thin light line under it is the container for the results that's now empty. The original select element does still have its options.
If I remove the livewire.emit from the js to test, the s2 behaves correctly.
I think it has to do with the components render method. I can't figure out what is happening different when I add versus remove.
I got this to work. The problem was the dropdownParent element I was using. I had it set to the modal. Setting it to the immediate parent element and it worked as expected.

Svelte input binding breaks when a reactive value is a reference type?

(I'm new to Svelte so it is quite likely that I'm doing something wrong here)
UPDATE: I've added a second, slightly different REPL which may demonstrate the problem better. Try this one: https://svelte.dev/repl/ad7a65894f8440ad9081102946472544?version=3.20.1
I've encountered a problem attempting to bind a text input to a reactive value.
I'm struggling to describe the problem in words, so hopefully a reduced demo of the issue in the attached REPL will make more sense.
https://svelte.dev/repl/6c8068ed4cc048919f71d87f9d020696?version=3.20.1
The demo contains two custom <Selector> components on a page.
The first component is passed two string values ("one" and "two"):
<Selector valueOne="one" valueTwo="two"/>
Clicking the buttons next to the input field sets selectedValue to one of these values.
This, in turn, triggers the following reactive declaration to update:
$: value = selectedValue
The input field is bound to this reactive value:
<input type="text" bind:value>
So clicking the "One" button sets the input text to "one", and clicking the "Two" button sets the input field to "two".
Importantly though, you can still type anything into the input field.
The second component is passed two array values:
<Selector valueOne={[1, "one"]} valueTwo={[2, "two"]}/>
Again, clicking the buttons sets selectedValue to one of these.
However this time the reactive declaration depends on an array element:
$: value = selectedValue[1]
Everything works as before, except now you can no longer type into the input field at all.
So the question is - why does <input bind:value> behave differently for these two:
$: value = aString
vs
$: value = anArray[x]
It seems that this is only an issue when using two-way bindings.
By switching to a one-way and an on:input handler, the problem goes away:
i.e. instead of this:
<input type="text" bind:value={valX}/>
use this:
<input type="text" value={valX} on:input={e => valX = e.target.value}/>
I'm pretty sure your reactive declaration is overwriting your bound value as soon as it changes, which is with every key stroke on the input and every button press. Meaning it technically is working, you're just reverting it each time it changes. Check out this version of it that uses a watcher.
Also binding to a reactive declaration means you're never actually changing the variables with the input (which you can see in your JSON result on the first selector when you type in the input the value doesn't update only on button click).
Why not lose the reactive declaration and bind directly to the variable you want. Then use an {#if} block to switch between which version of the input you're showing based on the truthiness of index?
<script>
export let valueOne;
export let valueTwo;
export let index;
let selectedValue = index? [] : '';
let selectValue = (val) => selectedValue = val;
</script>
{#if index}
<input type="text" bind:value={selectedValue[index]} placeholder="Type anything...">
{:else}
<input type="text" bind:value={selectedValue} placeholder="Type anything...">
{/if}
<button on:click={() => selectValue(valueOne)}>One</button>
<button on:click={() => selectValue(valueTwo)}>Two</button>
<p>
<strong>Selected value:</strong> {JSON.stringify(selectedValue)}
</p>
By binding directly to the selectedValue or an index of it you have the added benefit of changing the value with the input. Here's a working example in the REPL

jquery mobile selectmenu not working in chrome

I have a jquery-mobile selectmenu that has previously worked fine in both Safari and Chrome, but just recently the selectmenu won't select the option choice. It still works fine in Safari. When using development tools either from an emulator or chrome on my desktop, I get no errors. I do have an issue with glyphicons-halflings-regular.woff2 not loading and I have tried all of the suggestions found here on stack, but none of those seem to work and most all research I've done comes up with answers that are >4 yrs old.
I'm using jquery mobile 1.4.5 and bootstrap 3.3.6 and the application resides on Azure.
Here's what I've got right now...
<div class="ui-field-contain" id="regionDiv">
<label for="region">Region:</label>
<select class="text-left" name="select-region" id="region" data-native-menu="false" data-mini="true" onchange="changeRegion();"></select>
</div>
<div class="ui-field-contain">
<label for="projectmob">Project:</label>
<select class="text-left" name="select-proj" id="projectmob" data-native-menu="false" data-mini="true" onchange="dwmChange();"></select>
</div>
Both the region and the project selectmenus do not select the item, they just leave a blank box or won't let you select the item.
The .js that runs when selected (I think it is fine)...
function changeRegion()
{
var regid = Number($("#region").val());
var projsel = $("#projectmob");
projsel.empty();
projsel.append("<option id='selproj' value='placeholder' data-placeholder='true'>Select Project...</option>");
var projNumber = 0;
var projValue = -1;
for (var i = 0; i < proj.length; i++) {
if (proj[i].region == regid) {
projNumber++;
projsel.append("<option id='oc1-" + proj[i].id + "' value='" + proj[i].id + "'>" + proj[i].wono + ': ' + proj[i].name + "</option>");
projValue = proj[i].id;
};
};
$("#projectmob").selectmenu('refresh', true);
if (projNumber == 1) {
$("#projectmob").val(projValue).selectmenu('refresh');
};
getFilteredEvents();
}
function dwmChange()
{
var projid = Number($("#projectmob").val());
if (projid > 0) {
getFilteredEvents();
var regValue = findRegion(projid);
$("#region").val(regValue).selectmenu('refresh');
};
}
getFilteredEvents(); hits the azure sql database and sets up the screen with the data retrieved.
This all ran fine up until about a week ago as far as I know. I have made changes and updates, but none that I think should affect the selectmenus from working.
Any thoughts or ideas would be appreciated.
Thanks
It seems a problem with Chrome 50.0.2661.89.
Looking further into this...
I have to question the logic behind JQuery Mobile hiding the toolbars on select >element focus by default. The native browser select elements overlay the page in >their various special ways, and even the non-native select popup (which you get >when specify the data attribute data-native-menu="false" in html or nativeMenu: >false in the selectmenu options) is absolutely positioned as a dialog. This >means that the toolbars really do not intrude on the real-estate given to the >selectmenu options as they'll always overlay everything including the toolbars. >To me, this makes the code from line 12664 - 12692 commented as: this hides the >toolbars on a keyboard pop to give more screen room rather unnecessary for >select elements.
Workaround/solution: thankfully jQuery-Mobile does nicely allow you to override >this setting in your header/footer with the data-attribute data-hide-during->focus - simply set this to:
data-hide-during-focus="input, textarea"
and it won't try to hide the toolbars anymore when a select element gets focus."
From https://github.com/jquery/jquery-mobile/issues/8429

jquerymobile datebox - How to call a function when date selected

I have inherited some code using the jquerymobile datebox. The code so far concentrates on making the application look correct. I need to make it work so that when a date is selected, the server is called with the date and a new page loaded. Most examples just change the date in the page.
The code so far is :-
$('#daycal').live('click', function() {
$('#catchdate').datebox('open');
});
$( "#catchdate" ).bind( "change", function(event, ui) {
$("#test1").val("xyz");
});
And
<div data-role="fieldcontain">
<label for="catchdate">Some Date</label>
<input name="catchdate" type="date" data-role="datebox" id="catchdate" data-options='{"mode":"calbox", "useNewStyle":true, "theme":true, "themeHeader":"f", "themeDateHigh":"f", "themeDatePick":"e", "themeDate":"f", "centerHoriz":true}' />
<input id="test1" type="text"/> <!-- Later changed to a function call -->
</div>
In my simple test I expected the text in the input to change when a date was selected.
I have seen an example using the bind to change event, but I cannot get it to work. In the example I was just changing the value in an input element, later this will be changed to a function call.
I also saw somewhere in my search for an answer, a comment that 'live' was deprecated.
Finally, I thought I could use closeCallback ('Callbacks ('openCallback' and 'closeCallback') are simple to work with...') but could not find any examples of how it should be used.
What changes do I need to make to obtain the functionality I need?
You could try using the close function of the date box, so that when user changes the date selection he makes and closes the date box you can call the server method with the selected date:
$('#DateSelectorId').bind('datebox', function (e, passed) {
if ( passed.method === 'close' ) {
// selected date
var date = $('#DateSelectorId').val();
// make your service method and change page to another page
}
});
think this can fix it
$('#catchdate').on('datebox', function(e, p) {
if ( p.method === 'close' ) {
alert('DO SOMETHING');
}
});
u can go and test it on Fiddle
**i think u need some validation check for input box empty or not

jquery-mobile create dynamic controlgroup and apply jquery-ui css [duplicate]

This question already has answers here:
Dynamic controlgroup and checkboxes unstyled
(6 answers)
Closed 8 years ago.
This is my code:
http://jsfiddle.net/YKvR3/34/
I would create a controlgroup with values that are in my array (name).
The problem is that when I click load button the values are added in a controlgroup but the jquery-ui styles are not loaded like in the image.
The controlgroup is not styled with jquery-ui mobile css.
$("#load").click(function(){
var name=["one","two"];
var html='<fieldset id="listPlayers" data-role="controlgroup"><legend><h1>Choose as many players as youd like to remove:</h1></legend>';
for ( var int = 0; int < 2; int++) {
html+='<input type="checkbox" name="checkbox-'+int+'a" id="checkbox-'+int+'a" class="custom" /><label for="checkbox-'+int+'a">'+name[int]+'</label>';
}
alert('<legend><h3>Choose as many players as you would like to remove:</h3></legend>'+html+'</fieldset');
$("#list").html(html+'</fieldset');
//$("#list").page();});​
What I am doing wrong?
Thanks.
$("#list").trigger('create');
From: jqm docs
if you generate new markup client-side or load in content via Ajax and inject it into a page, you can trigger the create event to handle the auto-initialization for all the plugins contained within the new markup. This can be triggered on any element (even the page div itself), saving you the task of manually initializing each plugin (listview button, select, etc.).
I do applogies if this post is too old and if my post isn't by the correct standard since it's the first time ever posting so please correct me if it's horribly bad :-]
But in case someone else comes across it, I had similar problems with how the dynamic data is displayed and I used the jsfiddles and comments above as a help, and this is what got mine to work, well somewhat near my solution, I don't have a button to load the data it's loaded automatically when the page is loaded.
Updated In my .html-file:
<div id="members"></div>
<input type="button" id="load" value="test"/>
Updated In my .js-file:
$("#load").click(function(){
var name = ["NameOne","NameTwo", "NameThree"];
var fset = '<fieldset data-role="controlgroup" id="members-ctrlgroup"><legend>This is a legend:</legend>';
var labels='';
for ( var i = 0; i < name.length; i++) {
labels += '<input type="checkbox" class="checkbox" id="c'
+ i
+ '"><label for="c'
+ i
+ '" data-iconpos="right">'
+ name[i]
+'</label>';
}
$("#members").html(fset+labels+'</fieldset>');
$("#members").trigger("create");
});
I know the "field" looks a bit weird how I divided it but I find it somewhat easier when it comes to getting the whole html-string correct in these cases.
Updated In order to have the rounded corners and have it as one controlgroup you'll have to have this approach instead. Just like the former posters showed.
Do note that the id with the checkbox and the label for= can tend to screw the output if they're not the same :-]
fiddle
In order to replace the content you should use .html(); instead of .append(), which adds the new content after the existing one.
After adding content to a jQuery Mobile Page you need to enhance the content, using for instance $("input[type='radio']").checkboxradio();
I was using
for( var i=0 ; i < html.length ; i++ ){
var spline = html[i].split("|");
inHTML = inHTML + " <input type=\"checkbox\" name=\"checkbox-"+i+"a\" id=\"checkbox-"+i+"a\" class=\"custom\" /> <label for=\"checkbox-"+i+"a\">"+ spline[0] +" , "+ spline[2] +"</label> ";
}
jq("fieldset#myFieldSet").empty();
jq("fieldset#myFieldSet" )
// Append the new rows to the body
.append( inHTML )
// Call the refresh method
.closest( "fieldset#myFieldSet" )
// Trigger if the new injected markup contain links or buttons that need to be enhanced
.trigger( "create" );

Resources